home *** CD-ROM | disk | FTP | other *** search
/ Computer Music Interactif…cial Edition 1999 Winter / cd 3.iso / mac / Mac / Shares / Midishare™1.68 / Development Tools / MidiShareHelp < prev    next >
Encoding:
Text File  |  1993-02-03  |  139.8 KB  |  4,648 lines  |  [TEXT/MPS ]

  1. æKY CopyrightNotice
  2. æC  Copyright GRAME, Inc. 1989-1993.
  3.     Marketed under exclusif licence by TIME TECH
  4.             Time Tech
  5.             BP 256
  6.     69659 VILLEFRANCHE Cedex
  7.             France
  8.     All right reserved worlwide
  9. 411 - MidiShare Help version 1.67
  10. Mercredi 3 Février 1993 18:34:40
  11.  
  12. æKY Help
  13. MidiShareHelp
  14. æKL Foreword
  15. About_MidiShare
  16. Opening_Closing
  17. Communications
  18. Sending_Receiving
  19. Event_managing
  20. Sequence_managing
  21. Real_time_tasks
  22. Synchronisation
  23. Typology
  24. Data_structure
  25. Error_Codes
  26. Change_Codes
  27.  
  28. MidiAddField
  29. MidiAddSeq
  30. MidiApplySeq
  31. MidiAvailEv
  32. MidiCall
  33. MidiClearSeq
  34. MidiClose
  35. MidiConnect
  36. MidiCopyEv
  37. MidiCountAppls
  38. MidiCountDTasks
  39. MidiCountEvs
  40. MidiCountFields
  41. MidiDTask
  42. MidiExec1DTask
  43. MidiExt2IntTime
  44. MidiFlushDTasks
  45. MidiFlushEvs
  46. MidiForgetTask
  47. MidiFreeCell
  48. MidiFreeEv
  49. MidiFreeSeq
  50. MidiFreeSpace
  51. MidiGetApplAlarm
  52. MidiGetEv
  53. MidiGetExtTime
  54. MidiGetField
  55. MidiGetFilter
  56. MidiGetIndAppl
  57. MidiGetInfo
  58. MidiGetName
  59. MidiGetNamedAppl
  60. MidiGetPortState
  61. MidiGetRcvAlarm
  62. MidiGetSyncInfo
  63. MidiGetTime
  64. MidiGetVersion
  65. MidiGrowSpace
  66. MidiInt2ExtTime
  67. MidiIsConnected
  68. MidiNewCell
  69. MidiNewEv
  70. MidiNewSeq
  71. MidiOpen
  72. MidiReadSync
  73. MidiSend
  74. MidiSendAt
  75. MidiSendIm
  76. MidiSetApplAlarm
  77. MidiSetField
  78. MidiSetFilter
  79. MidiSetInfo
  80. MidiSetName
  81. MidiSetPortState
  82. MidiSetRcvAlarm
  83. MidiSetSyncMode
  84. MidiShare
  85. MidiSmpte2Time
  86. MidiTask
  87. MidiTime2Smpte
  88. MidiTotalSpace
  89. MidiWriteSync
  90.  
  91. typeActiveSens
  92. typeChanPress
  93. typeClock
  94. typeContinue
  95. typeCopyrigth
  96. typeCtrl14b
  97. typeCtrlChange
  98. typeChanPrefix
  99. typeCuePoint
  100. typeDProcess
  101. typeEndTrack
  102. typeInstrName
  103. typeKeyOff
  104. typeKeyOn
  105. typeKeyPress
  106. typeKeySign
  107. typeLyric
  108. typeMarker
  109. typeNonRegParam
  110. typeNote
  111. typePitchWheel
  112. typePrivate
  113. typeProcess
  114. typeProgChange
  115. typeQuarterFrame
  116. typeRegParam
  117. typeReserved
  118. typeReset
  119. typeSeqName
  120. typeSeqNum
  121. typeSMPTEOffset
  122. typeSongPos
  123. typeSongSel
  124. typeSpecific
  125. typeStart
  126. typeStop
  127. typeStream
  128. typeSysEx
  129. typeTempo
  130. typeText
  131. typeTimeSign
  132. typeTune
  133.  
  134.  
  135.  
  136. æKY Foreword
  137. æC 
  138.  
  139. MidiShare is a multi-tasking, real-time MIDI operating system, specially devised
  140. for the developing of MIDI applications with a triple target :
  141.  
  142. •To propose solutions to currently met problems when developing any MIDI application
  143. : MIDI communication, synchronisation and time management, task management, and
  144. memory management. 
  145.  
  146. •To enable the real-time and multi-tasking functioning of these applications, i.e.
  147. to enable the sharing of all the necessary resources and their simultaneous access.
  148.  
  149. •To make easier cooperation between independent MIDI applications by  proposing
  150.  a real-time  mechanism  of  inter-application communications.
  151.  
  152. The present document is intended for developers who wish to use MidiShare for the
  153. writing of MIDI applications. They will find here a complete description of all
  154. the MidiShare functions and procedures, as well as all the data structures in use.
  155.  
  156. Yann Orlarey and Hervé Lequay
  157.  
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165. æKY About_MidiShare
  166. æC 
  167.  
  168. The availability of multi-tasking operating systems such as Multi-Finder, Unix
  169. and OS/2 on microcomputers is a decisive advantage in many application areas and
  170. offers real gains in term of power and ease of use.
  171.  
  172. Unfortunately, until now musicians have hardly benefited at all from the advantages
  173. of such systems due to the lack of music applications capable of running simultaneously
  174. in real  time on a single machine. The internal layers of a Midi program often
  175. make use of critical resources of the computer such as timers, interrupts and serial
  176. link controllers which cannot be directly shared by more than one application,
  177. in addition, even multi-tasking operating systems are not generally a guarantee
  178. that applications run in real time.
  179.  
  180. MidiShare came into existence from this observation with the ambition to provide
  181. the frame needed to develop musical applications in a multi-tasks and real time
  182. context. When defining MidiShare, we have tried to conciliate three aims :
  183.  
  184. •    To propose solutions to the problems regularly met with in the development of
  185. all Midi applications.
  186.  
  187. •    To permit the simultaneous running of these applications, especially as regards
  188. real-time routines and Midi communications.
  189.  
  190. •    To allow for a cooperation between separately developed applications.
  191.  
  192. We are going to see how the various tools and services proposed by MidiShare comply
  193. with these objectives.
  194.  
  195. Events Managing
  196.  
  197. The whole system is based on the notion of event. An event is a dated entity possessing
  198. the informations for its own execution. The applications developed with MidiShare
  199. heavily relie on events to transmit and receive Midi messages but also to remember
  200. the tasks to be carried out.
  201.  
  202. It is generally not possible to use the host Operating System Memory Manager (MM)
  203. to deal with the allocation-deallocation of these events, since it revealed unadapted
  204. to a real-time context, non reentrant and inefficient, in terms of memory space
  205. when dealing with small zones of a few bytes. 
  206.  
  207. To make up for these lacks, MidiShare has its own dynamic memory allocation module,
  208. adapted to real-time constraints. For example, some functions permit to create
  209. or delete events (under interrupt too) with an extremely brief and constant time
  210. response. Moreover, these events can be accessed to and handled in a uniform and
  211. orthogonal way by a small number of routines which take automatically in charge
  212. the various memory structures (for, let us say, a constant size Key On and a variable
  213. size System Exclusive).
  214.  
  215. Communicating
  216.  
  217. The second essential point is the communications achievement. The applications
  218. running under MidiShare are not in charge of the communications physical execution
  219. but only deal with receiving and sending high-level events, for instance, complete
  220. Midi messages. In fact, MidiShare is internally in charge of translating events
  221. into corresponding Midi bytes sequences. Each application receives events into
  222. its own reception fifo. The application can consult this fifo anytime, extract
  223. and process the events waiting for treatment. Sending out events is easy as well.
  224. Stating the required output time and event to be transmitted will be sufficient.
  225.  
  226.  
  227. Midi multiple ports can of course be used. On some softwares, Midi Channels are
  228. numbered from 0 to 31 so as to take into account the two ports which can be used
  229. on Macintosh computers. We thought preferable to separate these two informations.
  230. This way, each MidiShare event has a channel number from 0 to 15 and a port number
  231. from 0 to 255; in the future, this will permit to deal with numerous Midi lines.
  232.  
  233. Time managing
  234.  
  235. It is obvious that a precise time control is essential for music. It is obvious
  236. too that according to the type of musical work carried out, different time representations
  237. are needed; which is why we chose the well-tried general solution consisting in
  238. an absolute representation of time in milliseconds over which other more "musical"
  239. representations can be built up by applications.
  240.  
  241. A 32 bits field defines the time for each MidiShare event. This field mentions
  242. the arrival time for the events received by an application or the required transmission
  243. time for events sent out by an application.
  244.  
  245. The algorithm used to manage the events scheduling is of course critical to the
  246. system’s performances. Several methods have been proposed. In this particular case,
  247. we have used an algorithm developed at first by one of the authors for MidiLisp.
  248. This very efficient algorithm ensures in all cases a bounded scheduling and dispatching
  249. time for treated events.
  250.  
  251. MidiShare can be synchronised to external Midi Time Code. In this case the MidiShare
  252. internal time unit accuratly follow the speed variations of the external Midi Time
  253. Code. Midi applications can be automatically informed when MidiShare start and
  254. stop being locked to external Midi Time Code.
  255.  
  256.  
  257. Tasks managing
  258.  
  259. Not only Midi messages are managed by MidiShare. Actually, an application having
  260. to remind a task to be done at a precise moment, can send to itself a particular
  261. type of message containing all the informations required for this task to be carried
  262. out. When arrived at maturity, this internal event is set by MidiShare in the application’s
  263. reception fifo as if it were an external event. The application’s reception routine
  264. will then accomplish the required task.
  265.  
  266. A second mechanism is implemented by MidiShare for tasks management. It is much
  267. more "procedural" and actually, very similar to Moxie’s "cause". It is in fact
  268. a delayed procedure call. For this to be done, MidiShare collects all the call
  269. parameters, together with the address of the routine to be called and generates
  270. a specific internal event. When this event has come to maturity, MidiShare restores
  271. the application context and actually deals with the call. It is to be noted that
  272. this call is made under interrupts, which means that some precautions have to be
  273. taken.
  274.  
  275. A third point related with tasks managing is the possibility for an application
  276. to define a reception alarm. It is a routine whose application gives MidiShare
  277. the address and which will be called each time new events are received (see example).
  278. Alarms therefore avoid an application having to consult periodically its reception
  279. fifo. Moreover, being called under interrupts, they allow for very efficient time
  280. responses.
  281.  
  282. Linking applications
  283.  
  284. As explained in the introduction, the reason for the creation of MidiShare was
  285. to permit several independent Midi applications to run simultaneously and to collaborate
  286. if necessary. This target may initially seem paradoxical. On the one hand, giving
  287. every application the impression to be the only user of the computer and consequently
  288. lessening the applications common resources. On the other hand, trying to connect
  289. these applications.
  290.  
  291. To isolate the applications was not a very difficult task. For instance, as regards
  292. incoming Midi messages, each application receives a different copy of them. Beside,
  293. every application possesses its own filters and reception fifo. There are no problems
  294. either to merge the various message transmissions, since they occur at the logical
  295. level too. Finally, as regards time, all applications refer to the same absolute
  296. clock in milliseconds, without having any influence on it.
  297.  
  298. How can we now link these applications ? Many users undoubtedly experienced Midi
  299. informations transfers, of musical sequences for instance, between two computers.
  300. We have taken over this idea and implemented inside MidiShare an internal real-time
  301. communication mechanism between applications.
  302.  
  303. Let us take a concrete example: two applications, the first being an echo generator,
  304. the second a sequencer. By default, these two applications are connected to the
  305. actual Midi I/O. However, it is quite possible to connect the output of the echo
  306. generator to the input of the sequencer. Each application is not aware of the connection
  307. change. 
  308.  
  309. There is no constraint in the way to connect applications between themselves. In
  310. particular, it is possible for an application to have multiple sources and multiple
  311. destinations, or else to be connected to itself (for example a sequencer recording
  312. itself). Furthermore, these connections can be dynamically reconfigured while the
  313. applications are running.
  314.  
  315.  
  316. æKY Opening_Closing
  317. æC 
  318.  
  319. First of all, an application must make sure that MidiShare is in memory. This checking
  320. is done thanks to the MidiShare function.
  321.  
  322. Then, you must call the MidiOpen installation function. This routine allows to
  323. record some information relative to the application context (its name, the value
  324. of A5 register, etc...), to affect a reception FIFO and to attribute a unique reference
  325. number to the application.
  326.  
  327. As a counterpart to any MidiOpen call, the application must call the MidiClose
  328. function before leaving, by giving its reference number as an argument. MidiShare
  329. can thus be aware of the precise number of active Midi applications. In theory,
  330. there is no objection to an application doing several MidiOpen, under the condition
  331. it realizes as many MidiClose. In all, there must not be more than 63 simultaneously
  332. opened Midi applications .
  333.  
  334. As long as no MidiOpen application is done, MidiShare is asleep and has no influence
  335. on the computer functioning. Following the first MidiOpen, MidiShare becomes active,
  336. it creates a task which will be called by an interruption  every  millisecond,
  337.  then  it  initiates  Acia interruption vectors and registers corresponding to
  338. Midi ports. MidiShare returns inactive after the last MidiClose.
  339.  
  340. æKY Communications
  341. æC 
  342.  
  343. For an application to be able to emit and receive events, it must first connect
  344. to a source and a destination. In fact, MidiShare is built on an internal communication
  345. mechanism allowing to exchange in real-time Midi events between active applications.
  346. An application is like a black box, receiving a flow of events in entry and producing
  347. a flow of events in output. This black box can be freely connected to other black
  348. boxes, thus forming an arbitrary complex network. This is one of the major points
  349. of MidiShare,  that allows a form of transparent and powerful collaboration between
  350. applications otherwise totally independent. 
  351.  
  352. "Real" Midi ins and outs are represented by a pseudo-application, which is always
  353. refereed to as number 0 and named "MidiShare", with which you just have to connect
  354. to communicate with the outside.
  355.  
  356. The implementation of these connections is very simple. The MidiConnect procedure
  357. allows to switch on or off a connection between a source application and a destination
  358. application. The MidiIsConnected function gives the state (on or off) of a connection.
  359. There is no restriction to the establishing of connections, an application can
  360. be source or destination as many times as you wish. Loops are permitted.
  361.  
  362. In some special cases, it is important that an application may get information
  363. on the other active MidiShare applications. The MidiCountAppls function gives the
  364. number of open  Midi applications. The MidiGetIndAppl function allows to know the
  365. reference number of any application by giving its order number (included between
  366. 1 and MidiCountAppls). It is also possible to find the reference number of an application
  367. thanks to its name using the MidiGetNamedAppl function. In the same way, knowing
  368. an application reference number, it is possible to find its name using the MidiGetName
  369. function. At last, the MidiSetName procedure allows to change the name of an application.
  370.  
  371. To be able to write more easily some "meta-applications" for the management of
  372. connections and other applications,  permanent information on context modifications
  373. into MidiShare (opening of new  applications,  changing connections, etc...)  is
  374.  highly requested. To do so, you just have to define a context alarm thanks to
  375. MidiSetApplAlarm and MidiGetApplAlarm routines. This alarm will be automatically
  376. called by MidiShare to inform the application of all the occurred changes.
  377.  
  378. æKY Sending_Receiving
  379. æC 
  380.  
  381. Once the connections have been established, the application can send and receive
  382. Midi events. Each application owns a reception fifo  in which MidiShare puts a
  383. copy of the received events. These come from other applications or from the different
  384. Midi ports in activity. MidiShare can in theory handle up to 256 ports. The implementation
  385. of Midi ports is controlled by the MidiSetPortState and MidiGetPortState routines.
  386. These must be used with care since they affect all the applications.
  387.  
  388. The MidiCountEvs function allows at any moment to know the number of events waiting
  389. in the reception fifo. This number is only limited by the memory size available
  390. for MidiShare. The events at disposal are picked up by repeated appeals to MidiGetEv
  391. function. The MidiAvailEv function is almost similar. It allows to read a received
  392. event, while leaving it in the fifo. The MidiFlushEvs procedure eliminates all
  393. the events on wait in the reception fifo.
  394.  
  395. The events received by an application are copies. The application can therefore
  396. freely dispose of them without any repercussion on the other applications. However,
  397. it must not forget to free them when it no longer needs them.
  398.  
  399. Each application can select the events to be received by using a filter. The filtering
  400. process is local to the application and has no influence on the events received
  401. by the other applications. The implementation of these filters is achieved by two
  402. routines : MidiSetFilter and MidiGetFilter.
  403.  
  404. MidiShare drives an internal absolute clock on 32 bits which is automatically switched
  405. on with the first MidiOpen and keeps running until the last MidiClose. This clock
  406. is used to date (in milliseconds) all the received events, as well as to specify
  407. the sending dates of events to be transmitted. Moreover, it provides all the applications
  408. with an absolute time reference. Its value can be read by the MidiGetTime function.
  409.  
  410.  
  411. Three routines allow to manage the transmissions. The MidiSendIm procedure allows
  412. the immediate emission of an event. The MidiSend and MidiSendAt procedures allow
  413. time delayed emissions, MidiShare automatically taking in charge the effective
  414. emissions at the scheduled time (thanks to that mechanism, an application can easily
  415. foresee emissions as accurately as to the millisecond and many days in advance).
  416.  
  417. Once an event is sent (by the means of MidiSend, MidiSendAt or MidiSendIm functions),
  418. it is no longer accessible by the application. This event must no longer be refereed
  419. to, under threat of irremediable disorganisation of the system. 
  420.  
  421. Example of what you must not do :
  422.  
  423. e = MidiNewEv (typeNote);    /* Typical example of fatal error    */
  424. MidiSendIm(myRefNum, e);    /* after having being sent, the “e” pointer    */
  425. f = MidiCopyEv(e);            /* no longer refers to any valid event    */
  426.  
  427. æKY Event_managing
  428. æC 
  429.  
  430. The memory management of a standard application is generally achieved by the computer
  431. "Memory Manager" (MM). The MM deals with dynamic allocation and freeing memory
  432. blocks of arbitrary length, as well as memory compacting when necessary (excessive
  433. fragmentation of the memory). Unfortunately, a traditional MM is proved unadapted
  434. to a real time context. As a matter of fact :
  435.  
  436. • Only large blocks can be allocated efficiently by traditional MM. For example,
  437. the Macintosh MM needs 12 more bytes by allocated blocks, which is prohibitive
  438. for the very small group of bytes represented by a Midi event.
  439.  
  440. • The allocation time of a block is not constant, but depends on many factors,
  441. one of which being the fragmentation state of the memory. It can be very long if
  442. a memory compaction proves necessary. A traditional MM cannot guarantee the response
  443. time.
  444.  
  445. • A traditional MM is not re-entrant. No routine under interruption can  therefore
  446.  use  it  directly  or  indirectly, without irremediably disorganizing the memory
  447. space.
  448.  
  449. To overcome these inadaptations, MidiShare holds its own memory manager, adapted
  450. to the Midi event management and available under interruption. MidiShare drives
  451. a group of events common to all the applications. Each event has compulsory fields
  452. (date, channel, port, type, etc...) and variable fields that depend of its type.
  453.  
  454. The allocation is very easily done by MidiNewEv function which returns an event
  455. of a suitable type. The disallocation is as easily done by the MidiFreeEv procedure.
  456.  An other way of allocating an event is to duplicate an existing event by the MidiCopyEv
  457. function. It is possible to know at every moment the available space left by the
  458. MidiFreeSpace function.
  459.  
  460. The access to the compulsory fields of the event is directly done ; But the access
  461. to the variable fields is achieved thru the MidiSetField and MidiGetField functions.
  462.  
  463.  
  464. Some categories of events do not have a fixed number of fields. Such is the case,
  465. for example, for the Exclusive System messages. The MidiCountFields function gives
  466. the number of variable fields of an event. The MidiAddField procedure allows to
  467. add a field at the tail of an event of variable length.
  468.  
  469. For some special treatments, it may be useful to have access to the basic functions
  470. of the memory manager. All the events managed by MidiShare are implemented from
  471. fixed-sized cells (16 bytes). Most of the events need just one cell. Others like
  472. the Exclusive Systems use a variable number of cells linked to one another. The
  473. user application normally does not have to worry about those storage "details".
  474. Nevertheless, two functions are provided for this low level memory management.
  475. The first one, MidiNewCell, allows to allocate a simple cell. The second one, MidiFreeCell,
  476. operates the reverse and de-allocates a cell.
  477.  
  478. æKY Sequence_managing
  479. æC 
  480.  
  481. MidiShare offers basic functionalities for the managing  of sequences  of time
  482. ordered events.  The  MidiNewSeq function allocates a new sequence, empty at the
  483. start. The MidiAddSeq procedure inserts an event into a sequence, maintaining the
  484. time ordered dates. 
  485.  
  486. The MidiApplySeq procedure is an iterator. It allows to apply a procedure to all
  487. the events of a sequence.  The MidiClearSeq procedure frees the content of one
  488. sequence and the MidiFreeSeq procedure frees the sequence and its content.
  489.  
  490. æKY Real_time_tasks
  491. æC 
  492.  
  493. The alarm concept is the basis of the MidiShare scheduling mechanism. An alarm
  494. is a procedure whose address is sent to MidiShare by the application. Then, MidiShare
  495. will call this procedure in real time and often under interruption, to indicate
  496. the occurrence of an event. 
  497.  
  498. Each application can define two categories of alarms. The first category is defined
  499. by the MidiSetApplAlarm procedure. It warns of any change in the global context
  500. of MidiShare (see paragraph "Communications and connections"). The second category
  501. is defined by the MidiSetRcvAlarm procedure. It warns of the presence of new events
  502. in the reception fifo. This alarm is always called under interruption. Therefore,
  503. it must not use either directly or indirectly the Macintosh Memory Manager. On
  504. the reverse, it can have a free access to all the MidiShare functions (excepted
  505. MidiOpen and MidiClose), in particular event management. It can also have access
  506. to global variables of the application, because before the call, MidiShare restores
  507. its context register. 
  508.  
  509. The Macintosh  desk accessories cannot have global variables. To make up for this
  510. drawback, The MidiSetInfo routine allows each application to define a data area.
  511. This area remains accessible by MidiGetInfo function, even during the alarm, and
  512. it also serves as a global context to desk accessories and other purposes.
  513.  
  514. Once the RcvAlarm set, the application can easily organise its real-time tasks
  515. thanks to the private event concept. On the reverse of traditional Midi events,
  516. private events are meant for Midi equipments, but are messages that the application
  517. sends to itself. The application generally makes use of them to remember a task
  518. to be done on a precise date.
  519.  
  520. Therefore, when the date of a private event falls due, MidiShare sets the event
  521. into the application reception fifo, waiting there to be picked up and handled
  522. in the same way as Midi events.
  523.  
  524. MidiShare implements a second mechanism to manage the tasks. This is a time-delayed
  525. procedure call done thanks to MidiTask (or MidiCall) and MidiDTask procedures.
  526. To achieve this call, MidiShare collects all the call arguments, as well as the
  527. routine address to be called and trigs a special event (typeProcess or typeDProcess).
  528. When a typeProcess event falls in, MidiShare restores the application context and
  529. does proceed to the call. On the reverse, when a typeDProcess event falls in, it
  530. is not processed, but set on a waiting list belonging to the application. This
  531. one will have plenty of time to process the waiting tasks when time comes, owing
  532. to MidiCountDTasks (giving the number of tasks on wait) and MidiExec1DTask (processing
  533. the next task on wait) functions. 
  534.  
  535. As the MidiTasks are processed under interruption, they are not allowed to call
  536. directly or indirectly the operating system. The MidiDTasks allow to by-pass this
  537. obstacle since the application trigs their processing (generally in the main loop).
  538.  
  539. Under  certain circumstances,  "forgetting" a MidiTask or  a MidiDTask already
  540. launched but not yet processed, can be useful. The MidiForgetTask function will
  541. be used for that purpose. An application  MidiDTask  waiting  list  can  be  deleted
  542.  by MidiFlushDTasks function. 
  543.  
  544. At last, in order to make easier communication between the application tasks and
  545. to manage accesses, shared between certain variables, two ininterruptible, pointer-handling
  546. routines can be used. The MidiReadSync function reads and sets to NIL a memory
  547. address. The MidiWriteSync function updates an address only if NIL.
  548.  
  549. æKY Synchronisation
  550. æC 
  551.  
  552. MidiShare can be synchronised to external Midi Time Code (MTC) using the MidiSetSyncMode
  553. function. MidiSetSyncMode takes one parameter describing the choosed synchronisation
  554. mode (internal or external) and the synchronisation input port to be used. The
  555. synchronisation mode is global and all Midi applications are concerned. The function
  556. MidiGetSyncInfo provides informations about the synchronisation process. 
  557.  
  558. When the synchronisation mode is set to internal (the default mode), MidiShare
  559. is drived by an internal interrupt every millisecond. The "size" of the MidiShare
  560. time unit is one millisecond. The function MidiGetTime gives MidiShare internal
  561. time, the time elapsed since the very first MidiOpen, expressed in millisecond.
  562.  
  563. When the synchronisation mode is set to external, MidiShare start looking for incomming
  564. MTC. When enough MTC are detected, MidiShare became locked. It warns all the Midi
  565. applications, by calling their ApplAlarm, if any, with code MidiSyncStart. A typical
  566. sequencer may use this information to start playing a sequence according to the
  567. position of the tape. The function MidiGetExtTime returns the position of the tape
  568. in milliseconds.
  569.  
  570. When incomming MTC desappears, MidiShare became unlocked. It automatically adjust
  571. its time unit to one millisecond and again warns the midi applications via their
  572. ApplAlarm. with the code MidiSyncStop. A typical sequencer application may decide
  573. to stop playing its sequences.
  574.  
  575. While MidiShare is locked, it will maintains a constant offset between its internal
  576. time and the external time (the time of the tape) by automatically adjusting  the
  577. size of the time unit to follow the speed variations of the incomming MTC. The
  578. size of the MidiShare time unit will be exactly one millisecond when the MTC runs
  579. at its nominal speed, it will increase when the MTC slow down and decrease when
  580. the MTC speed up. For example with a MTC format of 25 frames/second, one frame
  581. represents 40 milliseconds (1000/25). In this case MidiShare will adjust the size
  582. of its time unit in order to always have 40 time units per frame whatever the actual
  583. speed of the incomming MTC is. Consequently, from the point of view of a Midi application,
  584. the duration of one frame at 25 frames/seconds will always be 40 milliseconds.
  585.  
  586. The function MidiGetExtTime returns the external time (the time of the tape expressed
  587. in milliseconds). While MidiShare is locked:
  588.  
  589.      MidiGetTime() - MidiGetExtTime() == constant offset
  590.  
  591. the difference between the MidiShare internal time and the tape time expressed
  592. in millisecond is a constant. Two functions are provided to make conversion between
  593. external and internal time : MidiInt2ExtTime and MidiExt2IntTime. We have:
  594.  
  595.     MidiInt2ExtTime( MidiGetTime() ) == MidiGetExtTime()
  596.  
  597.     MidiExt2IntTime( MidiGetExtTime() ) == MidiGetTime()
  598.  
  599. Two additional functions, MidiTime2Smpte and MidiSmpte2Time, are provided to make
  600. conversions between time expressed in millisecond and SMPTE locations. For example:
  601. MidiTime2Smpte( MidiGetExtTime(), 3, &loc ) set loc with the current smpte location
  602. of the tape using smpte format 3 (30 frames / seconds).
  603.  
  604. These functions can be used to convert smpte locations from one format to another.
  605. For example suppose we want to convert an smpte location from its current format
  606. to 30 drop frame. we can write: MidiTime2Smpte( MidiSmpte2Time (&loc), 2, &loc);
  607. where 2 means 30 drop frame.
  608.  
  609.  
  610.  
  611. æKY Typology
  612. æC 
  613.  
  614. The listing below presents the different types of MidiShare handled events. This
  615. typology contains the whole of the standard Midi messages, plus  specific messages
  616. such as the typeNote corresponding to a note with its duration ;  The typeStream
  617. corresponds to a series of arbitrary bytes, possibly including data and status
  618. codes, sent directly without any processing; or the typePrivate that are application
  619. private messages.
  620.  
  621. All these codes may be used in the MidiNewEv function to allocate an event of the
  622. desirable type and are accessible in  an event evType field.
  623.  
  624. Name            Code    Comment             
  625. typeNote        0        pitch, vel and duration (16bits)
  626. typeKeyOn        1        pitch and vel
  627. typeKeyOff        2        pitch and vel
  628. typeKeyPress    3        pitch and press
  629. typeCtrlChange    4        ctrl and val
  630. typeProgChange    5        prog
  631. typeChanPress    6        press
  632. typePitchWheel    7        Lsb et Msb
  633.             
  634. typeSongPos        8        Lsb et Msb
  635. typeSongSel        9        song
  636. typeClock        10        -
  637. typeStart        11        -
  638. typeContinue    12        -
  639. typeStop        13        -
  640.  
  641. typeTune        14        -
  642. typeActiveSens    15        -
  643. typeReset        16        -
  644.  
  645. typeSysEx        17        data1..dataN
  646. typeStream        18        byte1..byteN
  647.             
  648. typePrivate        19..127    arg1, arg2, arg3, arg4
  649. typeProcess        128        arg1, arg2, arg3, arg4
  650. typeDProcess    129        arg1, arg2, arg3, arg4
  651. typeQFrame        130        msg type (0..7) and value
  652.  
  653. TypeCtrl14b     131
  654. TypeNonRegParam 132
  655. TypeRegParam    133
  656.  
  657. TypeSeqNum      134      extended types from MidiFile 1.0
  658. TypeText        135
  659. TypeCopyright   136
  660. TypeSeqName     137
  661. TypeInstrName   138
  662. TypeLyric       139
  663. TypeMarker      140
  664. TypeCuePoint    141
  665. TypeChanPrefix  142
  666. TypeEndTrack    143
  667. TypeTempo       144
  668. TypeSMPTEOffset 145
  669.  
  670. TypeTimeSign    146
  671. TypeKeySign     147
  672. TypeSpecific    148
  673.  
  674. TypeReserved    149..254
  675. TypeDead        255    -
  676.  
  677. æKY Data_structure
  678. æC 
  679.  
  680. The MidiShare memory management is organised around fixed-sized cells (16 bytes).
  681. All the events are composed of a header cell that may be followed by one or many
  682. extension cells. Figure 1 describes the different fields composing the basic cell
  683. :
  684.  
  685.     The Link field is a multi use link.    
  686.     The date field includes the falling in date of the event (from 0 to 231-1).  
  687.       The refNum field includes the application reference number sending this.   
  688.      The evType field indicates the type of the event.    
  689.     The Port field indicates the destination Midi port of the event.    
  690.     The Chan field indicates the Midi channel of the event. 
  691.  
  692. These six fields are always present and always have the same meaning, whatever
  693. the type of the event. Their access can be direct. The info part contains special
  694. fields the meaning of which depends on the type of the event. In some cases, Info
  695. contains a pointer to one or several extension cells. Direct access to the special
  696. fields is possible provided one takes into account the differences of memory storage.
  697. If not, the special functions MidiGetField and MidiSetField can be used. These
  698. ones hide the event internal structure and allow to have direct access to the special
  699.  fields  by  specifying an  index  between  0  and MidiCountFields - 1.
  700.  
  701.     
  702. Midi messages with 0, 1 or 2 data bytes, use only one cell, as shown in figure
  703. 2. These two supplementary fields are accessible by the MidiGetField and MidiSetField
  704. functions with index 0 and 1.
  705.  
  706.     
  707. The notes (figure 3) have three more fields at their disposal : 0, 1 and 2 for
  708. pitch, velocity and duration. The access functions MidiGetField and MidiSetField
  709. automatically detects the 8, 16 or 32 bit fields. 
  710.  
  711.     
  712. System Exclusive type messages or Stream type messages include variable number
  713. of fields. They use the structure described on figure 4, build with elementary
  714. cells linked one to another. The MidiGetField and MidiSetField functions are able
  715. to follow the links giving access to data. The MidiAddField procedure allows the
  716. addition of fields at the tail of the message.     
  717. The private or internal type events need the use of an extension cell. This one
  718. is composed of four 32 bits fields (from 0 to 3) being able to contain any information
  719. left to the choice of the application.
  720.  
  721. æKY Error_Codes
  722. æC 
  723.  
  724. List of the error codes returned by some MidiShare functions.
  725.  
  726. Name    Code    Comment
  727.  
  728. MIDIerrSpace    -1    No more space available in the freelist or too many applications
  729.  MIDIerrRefNum    -2    Bad reference number     
  730. MIDIerrBadType    -3    Bad type of event     
  731. MIDIerrIndex    -4    Wrong field index of                         access to an event 
  732.  
  733. æKY Change_Codes
  734. æC 
  735.  
  736. List of the change codes sended by MidiShare to ApplAlarm.
  737. When an application need to know about context modifications like opening and closing
  738. of applications, opening and closing of midi ports, changes in connections between
  739. applications, it can install an ApplAlarm (see MidiSetApplAlarm). This ApplAlarm
  740. is then called by MidiShare every time a context modification happens with a 32-bits
  741. code describing the modification. The hi 16-bits part of this code is the refNum
  742. of the application involved in the context modification, the low 16-bits part 
  743. describe the type of change as listed below.
  744.  
  745. Name    Code Mac    Code Atari    Comment
  746.  
  747. MIDIOpenAppl    1    -    A new application is opened
  748. MIDICloseAppl    2    -    An application is closed    
  749. MIDIChgName    3    -    The name of an application is changed    
  750. MIDIChgConnect    4    -    A connection is changed 
  751. MIDIOpenModem    5    -    The Modem port is opened 
  752. MIDICloseModem    6    -    The Modem Port is closed 
  753. MIDIOpenPrinter    7    -    The Printer port is opened 
  754. MIDIClosePrinter    8    -    The Printer Port is closed 
  755. MIDISyncStart        9    550     Start of synchronization
  756. MIDISyncStop         10    551     End of synchronization
  757. MIDIChangeSync       11    552     The synchronization mode is changed
  758.  
  759. æKY MidiAddField
  760. æT Function
  761. æDT MidiAddField( (MidiEvPtr)e, (long)v);
  762. æC 
  763.  
  764. Description
  765. Adds a field at the tail of an event of variable length (for example a System Exclusive
  766. or a Stream) and assigns to it the value transmitted as a parameter.
  767.  
  768. Prototype
  769. C Mac ANSI :    pascal void    MidiAddField (MidiEvPtr e, long v);
  770. Pascal Mac :    procedure    MidiAddField (e:MidiEvPtr; v:longint);
  771.  
  772. Arguments
  773. e :    a MidiEvPtr, it is a pointer to the event to be modified. 
  774. v :    a 32-bit integer, it is the value of the field to be added. This value is always
  775. a long for a purpose of uniformity, but it is internally translate to the right
  776. size (a byte in this case). The value of v is actually between 0 and 127 for a
  777. System Exclusive and between 0 and 255 for a Stream.
  778.  
  779. Example 1 (ANSI C)
  780. Creates the System Exclusive message "F0 67 18 05 F7"
  781.  
  782. MidiEvPtr    e;
  783.  
  784. e = MidiNewEv (typeSysEx);
  785. MidiAddField (e, 0x67L);
  786. MidiAddField (e, 0x18L);
  787. MidiAddField (e, 0x05L);
  788.  
  789. Note : the leading F0 byte and the tailing F7 byte are automatically added by MidiShare
  790. when the message is transmitted. They must not be added by the user.
  791.  
  792. Example 2 (ANSI C)
  793. Creates the Stream message "F8 F0 67 F8 18 05 F7" that mix a System Exclusive and
  794. two MidiClock (F8)
  795.  
  796. MidiEvPtr    e;
  797. long     i;
  798.  
  799. e = MidiNewEv(typeStream);
  800. MidiAddField (e, 0xF8L);
  801. MidiAddField (e, 0xF0L);
  802. MidiAddField (e, 0x67L);
  803. MidiAddField (e, 0xF8L);
  804. MidiAddField (e, 0x18L);
  805. MidiAddField (e, 0x05L);
  806. MidiAddField (e, 0xF7L);
  807.  
  808.  Note : Streams are sent without any transformation (no running status, no check
  809. of coherence). They can be used for example to send a long system exclusive split
  810. into several chunks with a little delay between. They can also be used as in the
  811. example to mix real time messages in a long system exclusive for maintaining synchronization.
  812.  
  813. Example 3 (ANSI C)
  814. Create a system exclusive message from an array of values:
  815.  
  816. char         tab[3] = {10, 20, 30};
  817. MidiEvPtr     aSysEx;
  818.  
  819. MidiEvPtr Array2SysEx( short len, char* vect, short chan, short port )
  820. {
  821.     MidiEvPtr e;
  822.     
  823.     e = MidiNewEv( typeSysEx );        /* a new, empty sysex    */
  824.     Chan(e) = chan; Port(e) = port;    /* set destination info    */
  825.     while (len—) MidiAddField(e, *vect++);    /* append fields    */
  826.     return e;
  827. }
  828.  
  829. aSysEx = Array2SysEx(3, tab, 0, 0);
  830.     
  831.  
  832. æKY MidiAddSeq
  833. æT Function
  834. æDT MidiAddSeq( (MidiSeqPtr)s, (MidiEvPtr)e);
  835. æC 
  836.  
  837. Description
  838. Inserts an event in a sequence while maintaining the dates in time order. 
  839.  
  840. Prototype
  841. C Mac ANSI    :    pascal void    MidiAddSeq (MidiSeqPtr s, MidiEvPtr e);
  842. Pascal Mac    :    procedure    MidiAddSeq (s:MidiSeqPtr; e:MidiEvPtr);
  843.  
  844. Arguments
  845. s :     a MidiSeqPtr, it is a pointer on the sequence to be modified. 
  846. e :        a MidiEvPtr, it is a pointer on the event to be added.
  847.  
  848. Example (ANSI C)
  849. Creates a sequence of 10 midi clock every 250 ms.
  850.  
  851. MidiSeqPtr    s;
  852. MidiEvPtr    e;
  853. long    d;
  854.  
  855. s = MidiNewSeq();
  856. for (d=0; d< 2500; d+=250) 
  857. {
  858.     e = MidiNewEv (typeClock);
  859.     Date(e) = d;
  860.     MidiAddSeq (s, e);
  861. }
  862.  
  863. Note : if you are concerned by speed, you must know that sequences are single linked
  864. lists of time ordered events, so it takes more time for MidiAddSeq to insert an
  865. event in the middle of a sequence that either at the beginning or at the end.
  866.  
  867. æKY MidiApplySeq
  868. æT Function
  869. æDT MidiApplySeq(MidiSeqPtr s, ApplyProcPtr MyProc);
  870. æC 
  871.  
  872. Description
  873. This procedure is an iterator. It allows to apply a procedure to all the events
  874. of a sequence.
  875.  
  876. Prototype of MidiApplySeq
  877. C Mac ANSI    :    pascal void    MidiApplySeq (MidiSeqPtr s, ApplyProcPtr                                 MyProc);
  878. Pascal Mac    :    procedure    MidiApplySeq (s:MidiSeqPtr;                                         Myproc:ApplyProcPtr
  879. );
  880.  
  881. Arguments of MidiApplySeq
  882. s :        a MidiSeqPtr, it is a pointer to the sequence to be browsed;
  883. MyProc :    a ApplyProcPtr is the address of the procedure to apply to each event
  884. of the sequence.
  885.  
  886. Prototype of MyProc
  887. C Mac ANSI    :    pascal void    MyProc (MidiEvPtr e);
  888. Pascal Mac    :    procedure    MyProc (e:MidiEvPtr);
  889.  
  890. Argument of MyProc
  891. e :    a MidiEvPtr, it is a pointer to the current event in the sequence.
  892.  
  893. Example (ANSI C)
  894. Transpose a sequence by one octave.
  895.  
  896. MidiSeqPtr    s;
  897.  
  898. void TransposeOctave (MidiEvPtr e)
  899. {
  900.     if ( EvType(e) == typeNote || EvType(e) == typeKeyOn || 
  901.         EvType(e) == typeKeyOff || EvType(e) == typeKeyPress )
  902.     {
  903.             Pitch(e) += 12;    /* normally one must check boundaries */
  904.     }
  905. }
  906.  
  907. MidiApplySeq(s, TransposeOctave);    /* s is a previously created sequence */
  908.  
  909. Note for Mac users : MidiShare was originally developed for Pascal on the Macintosh.
  910. Therefore, in C, all procedure passed as arguments of a MidiShare function must
  911. be declared as Pascal. In the previous example, TransposeOctave should be declared
  912. as : pascal void TransposeOctave (MidiEvPtr e)
  913.  
  914. æKY MidiAvailEv
  915. æT Function
  916. æDT MidiEvPtr myPtr= MidiAvailEv( (short)refnum) ; 
  917. æC 
  918.  
  919. Description
  920. Gives a pointer to the first event at the head of the reception fifo, without extracting
  921. it. MidiAvailEv can be used for very special purposes when one wants to test the
  922. first event in the reception fifo of the application, but without processing it.
  923.  
  924. Prototype
  925. C Mac ANSI    :    pascal MidiEvPtr    MidiAvailEv (short refnum) ; 
  926. Pascal Mac    :    Function    MidiAvailEv (refnum: integer) : MidiEvPtr;
  927.  
  928. Arguments
  929. refNum :     a 16-bit integer, it is the reference number of the application.
  930.  
  931. Result
  932. The result is a MidiEvPtr, a pointer to the first event in the reception fifo,
  933. or NIL if the reception fifo is empty.  
  934.  
  935. Example (ANSI C)
  936. A function that calculate for how long events have been waiting in the reception
  937. fifo.
  938.  
  939. long CalculateWaitTime (short refNum)
  940. {
  941.     MidiEvPtr    e;
  942.  
  943.     if (e = MidiAvailEv (refNum))
  944.         return MidiGetTime() - Date(e);
  945.     else
  946.         return 0;
  947. }
  948.  
  949. Note : as the event is still in the reception fifo, it must not be destroyed neither
  950. sent. It can just be tested or duplicated.
  951.  
  952. æKY MidiCall
  953. æT Function
  954. æDT MidiCall(TaskPtr MyProc, long date, short refNum, long a1, long a2, long a3);
  955. æC 
  956.  
  957. Description
  958. Defines a time delayed procedure call. When the calling date falls in, the call
  959. is automatically realized by MidiShare under interruptions. MidiCall is presented
  960. here for historical reasons, but MidiTask is a better choice.
  961.  
  962. Prototype of MidiCall
  963. C Mac ANSI    :    pascal void    MidiCall (TaskPtr MyProc, long date, 
  964.             short refNum, long a1, long a2, long a3);
  965. Pascal Mac    :    Procedure    MidiCall (MyProc:TaskPtr; date:longint; refNum:integer;
  966. a1,a2,a3: longint);  
  967.  
  968. Arguments of MidiCall
  969. MyProc     : a TaskPtr, it is the address of the procedure to be called.
  970. date     : a 32-bit integer, it is the date at which this call is scheduled. 
  971. refNum     : a 16-bit integer, it is the reference number of the application.
  972. a1,a2,a3     : are 32-bit integers left at the user’s disposal, as arguments of MyProc
  973.  
  974. Prototype of MyProc
  975. C Mac ANSI    :    pascal void    MyProc (long date, short refNum, 
  976.                     long a1, long a2, long a3);
  977. Pascal Mac    :    procedure    MyProc (date:longint; refNum:integer; 
  978.                             a1,a2,a3: longint);
  979.  
  980. Argument of MyProc
  981. date     : a 32-bit integer, it is the date of the call . 
  982. refNum     : a 16-bit integer, it is the reference number of the application.
  983. a1,a2,a3     : are 32-bit integers that can be freely used.
  984.  
  985. Example (ANSI C )
  986. Send periodicaly, every 10 ms, a MidiClock during 30 seconds.
  987.  
  988. void MyClock (long date, short refNum, long delay, long limit, long a3)
  989. {
  990.     if (date < limit)
  991.     {
  992.         MidiSendIm (refNum, MidiNewEv(typeClock));
  993.         MidiCall (MyClock, date+delay, refNum, delay, limit, a3);
  994.     }
  995. }
  996. ...........
  997. long d;
  998. ...........
  999. d = MidiGetTime();
  1000. MyClock (d, myRefNum, 10L, d+30000L, 0L);    /* Start now 
  1001.                                 the clock for 30s */
  1002.  
  1003. Note : This call being done under interruptions, a few precautions should be taken,
  1004. such as not invoking non-reentrant routines of the Operating System (such as the
  1005. Memory Manager on the Macintosh for example). On the contrary, most of the MidiShare
  1006. functions are reentrant, they can be used safely under interrupts.
  1007.  
  1008. Note for Mac users : MidiShare was originally developed for Pascal on the Macintosh.
  1009. Therefore, in C, all procedure passed as arguments of a MidiShare function should
  1010. be declared as Pascal. In the previous example, MyClock should be declared as :
  1011. pascal void MyClock(long date, short refNum, long delay, long limit, long a3);
  1012.  
  1013. æKY MidiClearSeq
  1014. æT Function
  1015. æDT MidiClearSeq( (MidiSeqPtr)s);
  1016. æC 
  1017.  
  1018. Description
  1019. Frees the content of a sequence. MidiClearSeq de-allocates all the events of the
  1020. given sequence. By consequence this sequence becomes empty.
  1021.  
  1022. Prototype
  1023. C Mac ANSI    :    pascal void    MidiClearSeq (MidiSeqPtr s);
  1024. Pascal Mac    :    procedure    MidiClearSeq (s:MidiSeqPtr); 
  1025.  
  1026. Arguments
  1027. s :    a MidiSeqPtr, it is a pointer on a sequence whose events are to be freed.
  1028.  
  1029. Example (ANSI C)
  1030. Suppress all but the first event of a sequence.
  1031.  
  1032. void ClearAllButFirst (MidiSeqPtr s)
  1033. {
  1034.     MidiEvPtr e;
  1035.     
  1036.     if (s && First(s))            /* Check a non empty sequence */
  1037.     {
  1038.         e = MidiCopyEv(First(s));    /* make a safe copy of the                                         first event    */
  1039.         MidiClearSeq(s);    /* clear the content of the sequence     */
  1040.         MidiAddSeq(s, e);    /* add the event to the empty sequence    */
  1041.     }
  1042. }
  1043.         
  1044. Note : a sequence consist of a header of 4 pointers. The first one points to the
  1045. first event of the sequence. The second one points to the last event. The other
  1046. two pointers are reserved for future extensions and must be NIL. In an empty sequence,
  1047. the pointers to the first and last events are NIL.
  1048.  
  1049. æKY MidiClose
  1050. æT Function
  1051. æDT MidiClose( (short)refNum);
  1052. æC 
  1053.  
  1054. Description
  1055. Closing of a MidiShare application. Every opening of MidiShare with MidiOpen must
  1056. be counter-balanced by a call to MidiClose, so that MidiShare keeps the exact account
  1057. of active applications and released the corresponding internal data structures.
  1058. All the MidiShare applications owning a "context alarm" will be informed of this
  1059. closing.
  1060.  
  1061. Prototype
  1062. C Mac ANSI    :    pascal void    MidiClose (short refNum);
  1063. Pascal Mac    :    procedure    MidiClose (refNum:integer);
  1064.  
  1065. Arguments
  1066. refNum :    a 16-bit integer, it is the reference number of the application, given
  1067. by the corresponding MidiOpen.
  1068.  
  1069. Example (ANSI C)
  1070. A DoNothing MidiShare application.
  1071.  
  1072. #include MidiShare.h
  1073. #include <stdio.h>
  1074.  
  1075. short    myRefNum;
  1076.  
  1077. main()
  1078. {
  1079.     if ( ! MidiShare() )     exit(1);        /* Check MidiShare loaded    */
  1080.     myRefNum = MidiOpen("Sample");            /* Ask for a reference number    */
  1081.     if ( myRefNum < 1 )     exit(1);        /* Check MidiOpen success    */
  1082.     printf( "refNum : %i \n", myRefNum);    /* Print the reference                                                 number
  1083.     */     MidiClose(myRefNum);                    /* And close*/
  1084. }
  1085.  
  1086. Note : MidiClose take care of deleting all the connections with the concerned application.
  1087. Therefore if an application sends some Midi events and without delay, does a MidiClose,
  1088. these sent events will probably not be actually transmitted. They just go back
  1089. to the MidiShare Memory Manager.
  1090.  
  1091. Note for Mac users : MidiShare was originally developed for Pascal on the Macintosh.
  1092. Therefore, in C, all strings passed as arguments of a MidiShare function must be
  1093. Pascal strings. In the previous example, one must write :      myRefNum = MidiOpen("\pSample");
  1094. æKY MidiConnect
  1095. æT Function
  1096. æDT MidiConnect(short src, short dest, boolean state);
  1097. æC 
  1098.  
  1099. Description
  1100. Connects or disconnects two applications. The MidiConnect procedure allows to switch
  1101. on or off a connection between a source application and a destination application.
  1102. There is no restrictions to the establishing of connections, an application can
  1103. be source or destination as many times as you wish. Loops are permitted.
  1104.  
  1105. Prototype
  1106. C Mac ANSI:         pascal void     MidiConnect (short src, short dest, 
  1107.             boolean state);
  1108. Pascal Mac:           Procedure     MidiConnect (src, dest:integer; 
  1109.             state:boolean);
  1110. Arguments
  1111. src :        a 16-bit integer, it is the reference number of the source application.
  1112.  dest :    a 16-bit integer, it is the reference number of the destination application.
  1113. state :    a boolean, it indicates if a connection must be switched on (True) or off
  1114. (False).
  1115.  
  1116. Example (ANSI C)
  1117. Open a MidiShare application and connect it to the physical Midi inputs and outputs.
  1118.  
  1119. #include MidiShare.h
  1120. #define PHYSMIDI_IO 0        /* The MidiShare physical Midi I/O ports*/
  1121.  
  1122. Main()
  1123. {
  1124.     short    myRefNum;
  1125.  
  1126.     myRefNum = MidiOpen("MidiSample");
  1127.  
  1128.     MidiConnect (PHYSMIDI_IO, myRefNum, TRUE);/* to receive events    */
  1129.     MidiConnect (myRefNum, 0, TRUE);          /* to transmit events    */
  1130.  
  1131.     /* ....... */
  1132.  
  1133.     MidiClose(myRefNum);
  1134. }
  1135.  
  1136. Note : the physical Midi inputs and outputs are represented by the pseudo application
  1137. called "MidiShare" with a reference number of 0 (zero). This pseudo application
  1138. is automatically created when MidiShare wakes up at the very first MidiOpen.
  1139.  
  1140. æKY MidiCopyEv
  1141. æT Function
  1142. æDT MidiEvPtr myPtr= MidiCopyEv( (MidiEvPtr)e);
  1143. æC 
  1144.  
  1145. Description
  1146. Duplicates an event. MidiCopyEv takes into account the structure of the event.
  1147. It can be used to copy every type of events, from simple notes to big system exclusives.
  1148.  
  1149. Prototype
  1150. C Mac ANSI    :    pascal MidiEvPtr    MidiCopyEv (MidiEvPtr e);
  1151. Pascal Mac    :            Function    MidiCopyEv (e: MidiEvPtr): MidiEvPtr;
  1152.  
  1153. Arguments
  1154. e :     a MidiEvPtr, it is a pointer to the event to be copied.
  1155.  
  1156. Result
  1157. The result is a MidiEvPtr, a pointer to the copy if the operation was successful.
  1158. The result is NIL if MidiShare was not able to allocate enough memory space for
  1159. the copy.
  1160.  
  1161. Example (ANSI C)
  1162. Send from now, 10 times an identical note of pitch 60 every 250 ms.
  1163.  
  1164. MidiEvPtr    e;
  1165. short        myRefNum;
  1166. long        d;
  1167. short        i;
  1168. ........
  1169.  
  1170. e = MidiNewEv (typeNote);    /* create template note    */
  1171. Pitch(e)= 60;                /* fill up its parameters    */
  1172. Vel(e)    = 80;
  1173. Dur(e)    = 250;
  1174. Chan(e)    = 0;
  1175. Port(e) = 0;
  1176.  
  1177. for (d=MidiGetTime(), i=0; i<10; i++, d+=250)     /* send the 10 copies */
  1178.     MidiSendAt (myRefNum, MidiCopyEv(e), d);      /*   of the template    */
  1179.  
  1180. MidiFreeEv(e);                                    /* and free the template */
  1181.  
  1182. Note : it is very important to note that, once an event is sent, it must never
  1183. be used any more by the application. Therefore, if one need to send several times
  1184. the same midi message, one must send different copies.
  1185.  
  1186. æKY MidiCountAppls
  1187. æT Function
  1188. æDT short myRet= MidiCountAppls();
  1189. æC 
  1190.  
  1191. Description
  1192. Gives the number of Midi applications on activity. 
  1193.  
  1194. Prototype
  1195. C Mac ANSI    :    pascal short    MidiCountAppls();
  1196. Pascal Mac    :        Function    MidiCountAppls : integer;
  1197.  
  1198. Result
  1199. The result is a 16-bit integer, the number of currently opened Midi applications.
  1200.  
  1201. Example (ANSI C)
  1202. Print the name of all the actives MidiShare applications
  1203.  
  1204. void PrintApplNames(void)
  1205. {
  1206.     short     ref;
  1207.     short     i;
  1208.     
  1209.     printf( "List of MidiShare applications :\n" );
  1210.     for( i = 1; i <= MidiCountAppls(); ++i )
  1211.     {
  1212.         ref = MidiGetIndAppl(i);
  1213.         printf("%i : %s \n", ref, MidiGetName( ref ) );
  1214.     }
  1215. }
  1216.  
  1217. Note for Mac users : MidiShare was originally developed for Pascal on the Macintosh.
  1218. Therefore, in C, the result of MidiGetName is a Pascal string that must be converted
  1219. to a C string before being printed.
  1220.  
  1221. æKY MidiCountDTasks
  1222. æT Function
  1223. æDT long myRet= MidiCountDTasks( (short)refNum);
  1224. æC 
  1225.  
  1226. Description
  1227. Returns the number of time delayed tasks waiting in the list of the application.
  1228. Delayed tasks are function calls that where scheduled with MidiDTask and that are
  1229. now ready to be executed in the DTasksFifo of the application.
  1230.  
  1231. Prototype
  1232. C Mac ANSI    :    pascal long    MidiCountDTasks (short refNum);
  1233. Pascal Mac    :    Function    MidiCountDTasks (refNum: integer): longint;
  1234.  
  1235. Arguments
  1236.  
  1237. refNum :     a 16-bit integer, the reference number of the application.
  1238.  
  1239. Result
  1240. The result is a 32-bit integer, the number of waiting DTasks.
  1241.  
  1242. Example (ANSI C)
  1243. Execute the waiting DTasks of a MidiShare application.
  1244.  
  1245. void ExecuteAllDTasks(short refNum)
  1246. {
  1247.     long    n;
  1248.  
  1249.     for (n=MidiCountDTasks(refNum), n>0; n—)
  1250.     {
  1251.         MidiExec1DTask(refNum);
  1252.     }
  1253. }
  1254.  
  1255. Note : This is what a typical application must do, generally in its main event
  1256. loop, to actually execute previously scheduled MidiDTasks. Since these MidiDTasks
  1257. are executed in the main event loop, they can do Operating System call without
  1258. trouble. In return, as MidiDTasks are not executed under interrupts, they are not
  1259. as accurate in time as MidiTasks.
  1260.  
  1261. æKY MidiCountEvs
  1262. æT Function
  1263. æDT long myRet= MidiCountEvs( (short)refnum);
  1264. æC 
  1265.  
  1266. Description
  1267. Gives the number of events on wait into the reception fifo of the application.
  1268.  
  1269. Prototype
  1270. C Mac ANSI    :    pascal long    MidiCountEvs (short refnum);
  1271. Pascal Mac    :    Function    MidiCountEvs (refnum: integer) : longint;
  1272.  
  1273. Arguments
  1274. refNum :     a 16-bit integer, the reference number of the application.
  1275.  
  1276. Result
  1277. The result is a 32-bit integer, the number of waiting events in the reception fifo.
  1278.  
  1279. Example (ANSI C)
  1280. A receive alarm that processes all the received events by adding to their date
  1281. a one second delay.
  1282.  
  1283. void OneSecDelay (short refNum)
  1284. {
  1285.     MidiEvPtr    e;
  1286.     long n;
  1287.  
  1288.     for ( n = MidiCountEvs(refNum); n > 0; —n ) 
  1289.     {                                
  1290.         e = MidiGetEv(refNum);    /* Get an event from the fifo    */
  1291.         Date(e) += 1000;        /* Add 1000 ms to its date    */
  1292.         MidiSend(refNum,e);        /* Then send the event        */
  1293.     }
  1294. }
  1295. ......
  1296. MidiSetRcvAlarm(myRefNum,OneSecDelay);/* Activate the receive alarm        */
  1297.  
  1298. Note : such a procedure can be called repeatedly in the main event loop of the
  1299. application, but for really accurate time control, it must be installed as a receive
  1300. alarm with MidiSetRcvAlarm.
  1301.  
  1302. Note for Mac users : MidiShare was originally developed for Pascal on the Macintosh.
  1303. Therefore, in C, all procedure passed as arguments of a MidiShare function must
  1304. be declared as Pascal. In the previous example, OneSecDelay must be declared as:
  1305.          pascal void OneSecDelay (short refNum)
  1306. æKY MidiCountFields
  1307. æT Function
  1308. æDT long myRet= MidiCountFields( (MidiEvPtr)e);
  1309. æC 
  1310.  
  1311. Description
  1312. Gives the number of fields of an event. 
  1313.  
  1314. Prototype
  1315. C Mac ANSI    :    pascal long    MidiCountFields (MidiEvPtr e);
  1316. Pascal Mac    :        Function    MidiCountFields (e: MidiEvPtr): longint;
  1317.  
  1318. Arguments
  1319. e :     a MidiEvPtr, a pointer to the concerned event.
  1320.  
  1321. Result
  1322. The result is a 32-bit integer, the number of fields of the event.
  1323.  
  1324. Example (ANSI C)
  1325. An universal method for printing of a MidiShare event.
  1326.  
  1327. void PrintEv(MidiEvPtr e)
  1328. {
  1329.     long i, n;
  1330.     n = MidiCountFields(e);
  1331.     printf( "Event %x content :\n", e );
  1332.     printf( " link : %x\n", Link(e) );
  1333.     printf( " date : %i\n", Date(e) );
  1334.     printf( " type : %i\n", EvType(e) );
  1335.     printf( "  ref : %i\n", RefNum(e) );
  1336.     printf( " port : %i\n", Port(e) );
  1337.     printf( " chan : %i\n", Chan(e) );
  1338.     printf( " %i fields : ( ", n );
  1339.     for(i=0; i<n; ++i) printf("%i ",MidiGetField(e,i) );
  1340.     printf( ")\n" );
  1341. }
  1342.  
  1343. Note : MidiShare events carry two kind of information : common information, like
  1344. date, type, channel, port ..., and specific information that depend of the type
  1345. of event. Fields allow a uniform way to access these specific information. Some
  1346. events have fixed number of fields (for example notes have three fields : pitch
  1347. (8-bit), velocity (8-bit) and duration (16-bit)). Some other, like system exclusive
  1348. have a variable number of fields.
  1349.  
  1350. æKY MidiDTask
  1351. æT Function
  1352. æDT MidiEvPtr myPtr= MidiDTask( (ProcPtr)MyProc, (long)date, (short)refNum, (long)a1, (long)a2, (long)a3);
  1353. æC 
  1354.  
  1355.  
  1356. Description
  1357. On the same way as MidiTask, MidiDTask allows to realize a time delayed procedure
  1358. call ; but on the reverse to MidiTask, the call is not achieved under interruption
  1359. as soon as falling time is due. The address of the routine to be executed and the
  1360. corresponding arguments will be stored into a special list. The application will
  1361. be allowed to process these on-wait tasks, one by one, thanks to MidiExec1DTask.
  1362.  
  1363. Prototype of MidiDTask
  1364. C Mac ANSI    :    pascal MidiEvPtr MidiDTask (ProcPtr MyProc, long date, short refNum,
  1365.                                     long a1, long a2, long a3); 
  1366. Pascal Mac:        Function    MidiDTask (MyProc:ProcPtr; date:longint; refNum:integer; 
  1367.                                     a1,a2,a3: longint):MidiEvPtr;
  1368.  
  1369.  
  1370. Arguments of MidiDTask
  1371. MyProc     : is the address of the procedure to be called.
  1372. date     : a 32-bit integer, it is the date at which this call is scheduled. 
  1373. refNum     : a 16-bit integer, it is the reference number of the application.
  1374. a1,a2,a3     : are 32-bit integers left at the user’s disposal, as arguments to MyProc
  1375.  
  1376. Result of MidiDTask
  1377. The result, a MidiEvPtr, is a pointer to a typeDProcess MidiShare event. The result
  1378. is NIL if MidiShare runs out of memory.
  1379.  
  1380. Prototype of MyProc
  1381. C Mac ANSI    :    pascal void    MyProc (long date, short refNum, 
  1382.                     long a1, long a2, long a3);
  1383. Pascal Mac    :    procedure    MyProc (date:longint; refNum:integer; 
  1384.                     a1,a2,a3: longint);
  1385.  
  1386. Argument of MyProc
  1387. date     : a 32-bit integer, it is the date of the call . 
  1388. refNum     : a 16-bit integer, it is the reference number of the application.
  1389. a1,a2,a3     : are 32-bit integers that can be freely used.
  1390.  
  1391.  
  1392. Example (ANSI C)
  1393.  
  1394. Schedule Action() procedure call 1000 ms ahead.
  1395.  
  1396. MidiEvPtr    myDTask;
  1397.  
  1398. MyDTask = MidiDTask(Action,MidiGetTime()+1000,myRefNum, a1, a2, a3);
  1399.  
  1400. Note : The result, in myDTask, can be used to test the success of MidiDTask. It
  1401. can also be used by MidiForgetTask to try to "forget" a scheduled task before it
  1402. happens.
  1403.  
  1404. æKY MidiExec1DTask
  1405. æT Function
  1406. æDT MidiExec1DTask( (short)refnum);
  1407. æC 
  1408.  
  1409. Description
  1410. Processes the first time delayed task on wait in the application list. The time
  1411. delayed tasks scheduled by MidiDTask are not processed as soon as time falls in,
  1412. but stored into a special list proper to each application, so they can be processed
  1413. out of interruption.
  1414.  
  1415. Prototype
  1416. C Mac ANSI    :    pascal void    MidiExec1DTask (short refnum);
  1417. Pascal Mac    :    procedure    MidiExec1DTask (refnum: integer);
  1418.  
  1419. Arguments
  1420. refNum     : a 16-bit integer, it is the reference number of the application.
  1421.  
  1422. Example (ANSI C)
  1423. Execute the waiting DTasks of a MidiShare application.
  1424.  
  1425. void ExecuteAllDTasks(short refNum)
  1426. {
  1427.     long    n;
  1428.  
  1429.     for (n=MidiCountDTasks(refNum), n>0; n—)
  1430.     {
  1431.         MidiExec1DTask(refNum);
  1432.     }
  1433. }
  1434.  
  1435. Note : This is what a typical application must do, generally in its main event
  1436. loop, to actually execute previously scheduled MidiDTasks. Since these MidiDTasks
  1437. are executed in the main event loop, they can do Operating System Call without
  1438. trouble. In return, as MidiDTasks are not executed under interrupts, they are not
  1439. as accurate in time as MidiTasks.
  1440.  
  1441. æKY MidiExt2IntTime
  1442. æT Function
  1443. æDT long  myRet= MidiExt2IntTime( (long)time)
  1444. æC 
  1445.  
  1446. Description
  1447. Convert an external time in millisecond to an internaltime. The convertion is made
  1448. by substractiong the current offset between internal and external time.
  1449.  
  1450. Prototypes
  1451. C Mac ANSI :     pascal long     MidiExt2IntTime (long time)
  1452. Pascal Mac :     Function     MidiExt2IntTime(time : longint): longint;
  1453.  
  1454. Arguments
  1455. time : a 32-bits time in milliseconds
  1456.  
  1457. Result
  1458. the corresponding internal time, a 32-bits value in milliseconds.
  1459.  
  1460. Note
  1461. When MidiShare is locked we have the following equivalence :
  1462.  
  1463. MidiExt2IntTime( MidiGetExtTime() ) == MidiGetTime()
  1464.  
  1465. We have also :
  1466.  
  1467. TSyncInfo     myInfo;
  1468. MidiGetSyncInfo(&myInfo);
  1469. MidiExt2IntTime(x) == x - myInfo.syncOffset
  1470.  
  1471.  
  1472. æKY MidiFlushDTasks
  1473. æT Function
  1474. æDT MidiFlushDTasks( (short)refnum);
  1475. æC 
  1476.  
  1477. Description
  1478. Flushes all the waiting DTasks in the application DTask list.
  1479.  
  1480. Prototype
  1481. C Mac ANSI    :    pascal void    MidiFlushDTasks (short refnum);
  1482. Pascal Mac    :    procedure    MidiFlushDTasks (refnum: integer);
  1483.  
  1484. Arguments
  1485. refNum     : a 16-bit integer, it is the reference number of the application.
  1486.  
  1487. Example (ANSI C)
  1488. Flushes all the waiting DTasks in the application DTask list.
  1489.  
  1490. short    myRefNum;
  1491.  
  1492. .....
  1493.  
  1494. MidiFlushDTasks (myRefNum);
  1495.  
  1496. æKY MidiFlushEvs
  1497. æT Function
  1498. æDT MidiFlushEvs( (short)refNum );
  1499. æC 
  1500.  
  1501. Description
  1502. Flushes all the waiting events in the reception fifo of the application.
  1503.  
  1504. Prototype
  1505. C Mac ANSI    :    pascal void    MidiFlushEvs( short refNum );
  1506. Pascal Mac    :    procedure    MidiFlushEvs( refNum : integer );
  1507.  
  1508. Arguments
  1509. refNum     : a 16-bit integer, it is the reference number of the application.
  1510.  
  1511. Example (ANSI C)
  1512. Flushes all the waiting events in the application reception fifo.
  1513.  
  1514. short    myRefNum;
  1515.  
  1516. .....
  1517.  
  1518. MidiFlushEvs (myRefNum);
  1519.  
  1520. æKY MidiForgetTask
  1521. æT Function
  1522. æDT MidiForgetTask( (MidiEvPtr *)e);
  1523. æC 
  1524.  
  1525. Description
  1526. Tries to "forget" a previously scheduled Task or DTasks. This a very powerful,
  1527. but dangerous function. One must be sure that the task is not yet executed before
  1528. calling MidiForgetTask.
  1529.  
  1530. Prototype
  1531. C Mac ANSI    :    pascal void    MidiForgetTask (MidiEvPtr *v);
  1532. Pascal Mac    :    procedure    MidiForgetTask (var v: MidiEvPtr);
  1533.  
  1534. Arguments
  1535. v :     is the address of a variable pointing to a previously scheduled Task or DTask
  1536. but not yet executed. The variable may also contain NIL. In this case MidiForgetTask
  1537. does nothing.
  1538.  
  1539. Side effect
  1540. The variable, which address is given in parameter, is set to NIL by MidiForgetTask.
  1541.  
  1542. Example 1 (ANSI C)
  1543. Create an infinite periodic clock (every 250ms) and stop it with MidiForgetTask.
  1544.  
  1545. MidiEvPtr    theClock;
  1546.  
  1547. void InfClock (long date, short refNum, long delay, long a2, long a3)
  1548. {
  1549.     MidiSendIm (refNum, MidiNewEv(typeClock));
  1550.     theClock = MidiTask (InfClock, date+delay, refNum, delay, a2, a3);
  1551. }
  1552.  
  1553. InfClock(MidiGetTime(), myRefNum, 250L, 0L, 0L);  /* Start the clock*/
  1554. .........                                         /* Wait some time    */
  1555. MidiForgetTask(&theClock);                        /* And forget it    */
  1556.  
  1557. Example 2 (ANSI C)
  1558.  
  1559. In the previous example theClock always point to a valid task because InfClock
  1560. never stop by itself. If the task may decide to stop itself, it must set the pointer
  1561. to NIL in order to avoid to forget an invalid task.
  1562.  
  1563. MidiEvPtr    theClock;
  1564.  
  1565. void CountClock (long date, short refNum, long delay,long count, long a3)
  1566. {
  1567.     if (count > 0)
  1568.     {
  1569.         MidiSendIm (refNum, MidiNewEv(typeClock));
  1570.         theClock = MidiTask (CountClock, date+delay, refNum, delay, count-1, a3);
  1571.     } else {
  1572.         theClock = NIL;     /* here the task decide to stop itself */ 
  1573.                             /* so set the pointer to NIL    */
  1574.     }
  1575. }
  1576.  
  1577. CountClock(MidiGetTime(), myRefNum, 250L, 100L, 0L);    /* Start 100                                                 clocks
  1578. */ .........                                /* Wait some time    */
  1579. MidiForgetTask(&theClock);                /* And forget it    */
  1580.  
  1581. If MidiForgetTask happens before the end of the 100 clocks, theClock point to a
  1582. valid task and MidiForgetTask(&theClock) is safe. If MidiForgetTask appens after
  1583. the end of the 100 clocks, theClock contains NIL and MidiForgetTask(&theClock)
  1584. is safe and will do nothing.
  1585.  
  1586. æKY MidiFreeCell
  1587. æT Function
  1588. æDT MidiFreeCell( (MidiEvPtr)c);
  1589. æC 
  1590.  
  1591. Description
  1592. Frees a cell allocated by MidiNewCell function. This is the lowest level for accessing
  1593. the MidiShare Memory Manager. One must be sure to use MidiFreeCell on an individual
  1594. cell allocated with MidiNewCell and not on complete MidiShare events. Not doing
  1595. so may result on losing cells.
  1596.  
  1597. Prototype
  1598. C Mac ANSI    :    pascal void    MidiFreeCell (MidiEvPtr c);
  1599. Pascal Mac    :    procedure    MidiFreeCell (c: MidiEvPtr);
  1600.  
  1601. Arguments
  1602. c :     a MidiEvPtr, a pointer to a basic cell of 16 bytes.
  1603.  
  1604. Example (ANSI C)
  1605. Free a cell previously allocated.
  1606.  
  1607. MidiEvPtr    aCell;
  1608.  
  1609. aCell = MidiNewCell();
  1610.  
  1611. ....
  1612.  
  1613. MidiFreeCell( aCell );
  1614.  
  1615. Note : Cells allocated with MidiNewCell must be freed with MidiFreeCell and not
  1616. with MidiFreeEv.
  1617.  
  1618. æKY MidiFreeEv
  1619. æT Function
  1620. æDT MidiFreeEv( (MidiEvPtr)e);
  1621. æC 
  1622.  
  1623. Description
  1624. Frees a MidiShare event allocated with MidiNewEv. MidiFreeEv takes into account
  1625. the event structure by checking the event type. For this reason, MidiFreeEv must
  1626. not be used on cell allocated with MidiNewCell. 
  1627.  
  1628. Prototype
  1629. C Mac ANSI    :    pascal void    MidiFreeEv (MidiEvPtr e);
  1630. Pascal Mac    :    procedure    MidiFreeEv (e: MidiEvPtr);
  1631.  
  1632. Arguments
  1633. e :     a MidiEvPtr, it is a pointer to a MidiShare event.
  1634.  
  1635. Example (ANSI C)
  1636. A receive alarm that delete all the received events.
  1637.  
  1638. short    myRefNum;
  1639. .....
  1640.  
  1641. void DeleteAll( short refNum )
  1642. {
  1643.     MidiEvPtr    e;
  1644.     long n;
  1645.  
  1646.     for ( n = MidiCountEvs(refNum); n > 0; —n ) 
  1647.     {                                
  1648.         e = MidiGetEv( refNum );    /* Get an event from the fifo    */
  1649.         MidiFreeEv( e );            /* Then free it            */
  1650.     }
  1651. }
  1652. ......
  1653.  
  1654. MidiSetRcvAlarm( myRefNum, DeleteAll );    /* Activate the receive alarm    */
  1655.  
  1656. Note : Obviously it is more simple and fast to use MidiFlushEvs to achieve the
  1657. same result.
  1658.  
  1659. Note for Mac users : MidiShare was originally developed for Pascal on the Macintosh.
  1660. Therefore, in C, all procedure passed as arguments of a MidiShare function must
  1661. be declared as Pascal. In the previous example, DeleteAll must be declared as :
  1662.     pascal void DeleteAll( short refNum )
  1663. æKY MidiFreeSeq
  1664. æT Function
  1665. æDT MidiFreeSeq( (MidiSeqPtr)s);
  1666. æC 
  1667.  
  1668. Description
  1669. Frees a sequence and its content. MidiFreeSeq first de-allocates all the events
  1670. of the given sequence and then the sequence header itself.
  1671.  
  1672. Prototype
  1673. C Mac ANSI    :    pascal void    MidiFreeSeq (MidiSeqPtr s);
  1674. Pascal Mac    :    procedure    MidiFreeSeq (s:MidiSeqPtr); 
  1675.  
  1676. Arguments
  1677. s :    a MidiSeqPtr, it is a pointer on a sequence to be freed.
  1678.  
  1679. Example (ANSI C)
  1680. Frees a previously allocated sequence s.
  1681.  
  1682. MidiSeqPtr    s;
  1683.  
  1684. s = MidiNewSeq();
  1685. ....
  1686. MidiFreeSeq(s);
  1687.  
  1688. Note : Once freed, s is no more a valid pointer.
  1689.  
  1690. æKY MidiFreeSpace
  1691. æT Function
  1692. æDT long myRet= MidiFreeSpace();
  1693. æC 
  1694.  
  1695. Description
  1696. Gives the available space. MidiFreeSpace allows to know at any time the number
  1697. of cells remaining available from the MidiShare memory manager.  
  1698.  
  1699. Prototype
  1700. C Mac ANSI    :    pascal long    MidiFreeSpace(void);
  1701. Pascal Mac    :       Function    MidiFreeSpace : longint;
  1702.  
  1703. Arguments
  1704. none
  1705.  
  1706. Result
  1707. The result is a 32-bit integer, the number of available free cells in the MidiShare
  1708. memory manager.
  1709.  
  1710. Example (ANSI C)
  1711. Print informations about MidiShare memory space.
  1712.  
  1713. void PrintMemInfo(void)
  1714. {
  1715.     printf("MidiShare memory :\n");
  1716.     printf(" free space  : %i cells\n", MidiFreeSpace());
  1717.     printf(" used space  : %i cells\n", MidiTotalSpace() - MidiFreeSpace());
  1718.     printf(" total space : %i cells\n", MidiTotalSpace());
  1719. }
  1720.  
  1721. Note : MidiFreeSpace inhibits all interrupts during its execution. If the remaining
  1722. space is very large MidiFreeSpace can take a long time to execute and may cause
  1723. overrun errors with fast incoming Midi data.
  1724.  
  1725. æKY MidiGetApplAlarm
  1726. æT Function
  1727. æDT ApplAlarmPtr myPtr= MidiGetApplAlarm( (short)refNum);
  1728. æC 
  1729.  
  1730. Description
  1731. Gives the context alarm of an application. MidiGetAlarm allows to know the address
  1732. of the context alarm procedure associated to the application. This alarm is automatically
  1733. called by MidiShare to inform the application of all the changes happened into
  1734. the active Midi applications (name or connection changes, closing, opening, etc.)
  1735.  
  1736. Prototype of MidiGetApplAlarm
  1737. C Mac ANSI    :    pascal ApplAlarmPtr    MidiGetApplAlarm(short refNum);
  1738. Pascal Mac    :       Function    MidiGetApplAlarm(refNum: integer): ApplAlarmPtr;
  1739.  
  1740. Arguments of MidiGetApplAlarm
  1741. refNum : a 16-bit integer, it is the reference number of the application.
  1742.  
  1743. Result
  1744. the result, a ApplAlarmPtr, is the address of the alarm routine or NIL if no such
  1745. routine where installed.
  1746.  
  1747. Prototype of an ApplAlarm routine
  1748. C Mac ANSI    :    pascal void    MyApplAlarm (short refNum, long code);
  1749. Pascal Mac    :    procedure    MyApplAlarm (refNum:integer; code:longint);
  1750.  
  1751. Argument of an ApplAlarm routine
  1752. refNum     : a 16-bit integer, it is the reference number of the application.
  1753. code     : a 32-bit integer, the context modification code. 
  1754.  
  1755. Example (ANSI C)
  1756. Disable temporarily the application context alarm.
  1757.  
  1758. ApplAlarmPtr p;
  1759. .....
  1760. p = MidiGetApplAlarm( myRefNum );
  1761. MidiSetApplAlarm( NIL );        /* Disable application context alarm*/
  1762. .....
  1763. MidiSetApplAlarm( p );            /* Restore application context alarm*/
  1764. æKY MidiGetEv
  1765. æT Function
  1766. æDT MidiEvPtr myPtr= MidiGetEv( (short)refNum) ; 
  1767. æC 
  1768.  
  1769. Description
  1770. Extracts the event on top of the reception fifo. The received events, stored automatically
  1771. by MidiShare in the application reception fifo, can be picked up by successive
  1772. calls to MidiGetEv function.
  1773.  
  1774. Prototype
  1775. C Mac ANSI    :    pascal MidiEvPtr    MidiGetEv (short refNum) ; 
  1776. Pascal Mac    :    Function    MidiGetEv (refNum: integer) : MidiEvPtr;
  1777.  
  1778. Arguments
  1779. refNum : a 16-bit integer, it is the reference number of the application.
  1780.  
  1781. Result
  1782. a MidiEvPtr, a pointer to the first event in the reception Fifo, or NIL if the
  1783. fifo is empty. The event is extracted form the reception fifo.
  1784.  
  1785. Example (ANSI C)
  1786. A receive alarm that processes all the received events by adding to their date
  1787. a one second delay.
  1788.  
  1789. void OneSecDelay (short refNum)
  1790. {
  1791.     MidiEvPtr    e;
  1792.     long n;
  1793.     for ( n = MidiCountEvs(refNum); n > 0; —n ) 
  1794.     {                                
  1795.         e = MidiGetEv(refNum);    /* Get an event from the fifo        */
  1796.         Date(e) += 1000;        /* Add 1000 ms to its date        */
  1797.         MidiSend(refNum,e);        /* Then send the event            */
  1798.     }
  1799. }
  1800. .....
  1801.  
  1802. MidiSetRcvAlarm(myRefNum,OneSecDelay);/* Activate the receive alarm    */
  1803.  
  1804. Note : such a procedure can be called repeatedly in the main event loop of the
  1805. application, but for really accurate time control, it must be installed as a receive
  1806. alarm with MidiSetRcvAlarm. Note for Mac users : MidiShare was originally developed
  1807. for Pascal on the Macintosh. Therefore, in C, all procedure passed as arguments
  1808. of a MidiShare function must be declared as Pascal. In the previous example, OneSecDelay
  1809. must be declared as:     pascal void OneSecDelay (short refNum)
  1810.  
  1811. æKY MidiGetExtTime
  1812. æT Function
  1813. æDT long  myRet= MidiGetExtTime();
  1814. æC 
  1815.  
  1816. Description
  1817. Gives the current external time, the position of the tape converted in milliseconds.
  1818.  
  1819. Prototypes
  1820. C Mac ANSI :     pascal long     MidiGetExtTime (void);
  1821. Pascal Mac :     FUNCTION     MidiGetExtTime : longint;
  1822.  
  1823. Arguments
  1824. none
  1825.  
  1826. Example (ANSI C)
  1827. Gives the SMPTE current location of the tape.
  1828.  
  1829. TSyncInfo     myInfo;
  1830. TSmpteLocation    myLoc;
  1831.  
  1832. MidiGetSyncInfo(&myInfo);
  1833. MidiTime2Smpte( MidiGetExtTime(), myInfo.syncFormat, &myLoc);
  1834.  
  1835. Note
  1836. When the tape is stopped, MidiGetExtTime returns the stop position of the tape
  1837. converted in milliseconds.
  1838.  
  1839. æKY MidiGetField
  1840. æT Function
  1841. æDT long myRet= MidiGetField( (MidiEvPtr)e, (long)f);
  1842. æC 
  1843.  
  1844. Description
  1845. Gives the i index field value of an event. Field index start from 0. Depending
  1846. of the event type and field nature, the field format can be 8, 16 or 32-bit. MidiGetField
  1847. deals with all the format conversion and the result is always a 32-bit integer.
  1848.  
  1849. Prototype
  1850. C Mac ANSI    :    pascal long    MidiGetField (MidiEvPtr e, long f);
  1851. Pascal Mac    :      Function    MidiGetField (e: MidiEvPtr; f: longint): longint;
  1852.  
  1853. Arguments
  1854. e :    a MidiEvPtr, it is a pointer on the event to be acces. 
  1855. f :    a 32-bit integer, it is the field number to be read (numbered from 0).
  1856.  
  1857. Result
  1858. The result is a 32-bit integer, the value of the field. Fields are considered as
  1859. unsigned. 
  1860.  
  1861. Example (ANSI C)
  1862. An universal method for printing of a MidiShare event.
  1863.  
  1864. void PrintEv(MidiEvPtr e)
  1865. {
  1866.     long i, n;
  1867.  
  1868.     n = MidiCountFields(e);
  1869.     printf( "Event %x content :\n", e );
  1870.     printf( " link : %x\n", Link(e) );
  1871.     printf( " date : %i\n", Date(e) );
  1872.     printf( " type : %i\n", EvType(e) );
  1873.     printf( "  ref : %i\n", RefNum(e) );
  1874.     printf( " port : %i\n", Port(e) );
  1875.     printf( " chan : %i\n", Chan(e) );
  1876.     printf( " %i fields : ( ", n );
  1877.     for(i=0; i<n; ++i) printf("%i ",MidiGetField(e,i) );
  1878.     printf( ")\n" );
  1879. }
  1880.  
  1881. Note : MidiShare events carry two kind of information : common information, like
  1882. date, type, channel, port ..., and specific information that depend of the type
  1883. of event. Fields allow a uniform way to acces these specific information. Some
  1884. events have fixed number of fields (for example notes have three fields : pitch
  1885. (8-bit), velocity (8-bit) and duration (16-bit)). Some other, like system exclusive
  1886. have a variable number of fields.
  1887.  
  1888. æKY MidiGetFilter
  1889. æT Function
  1890. æDT FilterPtr myPtr= MidiGetFilter( (short)refNum);
  1891. æC 
  1892.  
  1893. Description
  1894. Gives the associated filter of an application. Each application can select the
  1895. events to be received by using a filter. The filtering processus is local to the
  1896. application and has no influence on the events received by other applications.
  1897.  
  1898.  
  1899. Prototype
  1900. C Mac ANSI    :    pascal FilterPtr    MidiGetFilter (short refNum);
  1901. Pascal Mac    :      Function    MidiGetFilter (refNum: integer): FilterPtr;
  1902.  
  1903. Arguments
  1904. refNum :     a 16-bit integer, the reference number of the application
  1905.  
  1906. Result
  1907. the result is a FilterPtr, a pointer to the filter associated to the application,
  1908. or NIL if there is no such filter (in this case the application accepts any events)
  1909.  
  1910. Example (ANSI C)
  1911. << to be supplied >>
  1912.  
  1913. æKY MidiGetIndAppl
  1914. æT Function
  1915. æDT short myRet= MidiGetIndAppl( (short)index);
  1916. æC 
  1917.  
  1918. Description
  1919. Gives the reference of number of an application from is order number. The MidiGetIndAppl
  1920. function allows to know the reference number of any application by giving its order
  1921. number (a number between 1 and MidiCountAppls() ).
  1922.  
  1923. Prototype
  1924. C Mac ANSI    :    pascal short    MidiGetIndAppl (short index);
  1925. Pascal Mac    :      Function    MidiGetIndAppl (index: integer) : integer;
  1926.  
  1927. Arguments
  1928. index :     a 16-bit integer, it is the index number of an application between 1 and
  1929. MidiCountAppls().
  1930.  
  1931. Result
  1932. The result is an application reference number or MIDIerrIndex if the index is out
  1933. of range.
  1934.  
  1935. Example (ANSI C)
  1936.  
  1937. Print the name of all the actives MidiShare applications
  1938.  
  1939. void PrintApplNames(void)
  1940. {
  1941.     short     ref;
  1942.     short     i;
  1943.     
  1944.     printf( "List of MidiShare applications :\n" );
  1945.     for( i = 1; i <= MidiCountAppls(); ++i )
  1946.     {
  1947.         ref = MidiGetIndAppl(i);
  1948.         printf("%i : %s \n", ref, MidiGetName( ref ) );
  1949.     }
  1950. }
  1951.  
  1952. Note for Mac users : MidiShare was originaly developed for Pascal on the Macintosh.
  1953. Consequently, in C, the result of MidiGetName is a Pascal string that must be converted
  1954. to a C string before being printed.
  1955.  
  1956. æKY MidiGetInfo
  1957. æT Function
  1958. æDT void* myPtr= MidiGetInfo( (short)refNum );
  1959. æC 
  1960.  
  1961. Description
  1962. Gives the content of a 32-bit field an application can use for any purpose. This
  1963. field remains accessible by MidiGetInfo during alarms and interrupts. It can be
  1964. used as a global context if necessary (for example for desk accessories on the
  1965. Macintosh).
  1966.  
  1967. Prototype
  1968. C Mac ANSI    :    pascal void*    MidiGetInfo( short refNum );
  1969. Pascal Mac    :        Function    MidiGetInfo( refNum: integer ) : Ptr;
  1970.  
  1971. Arguments
  1972. refNum :     a 16-bit integer, the reference number of the application
  1973.  
  1974. Result
  1975. The result is a 32-bit integer, the last value set by MidiSetInfo
  1976.  
  1977. Example (ANSI C)
  1978. << to be supplied >>
  1979.  
  1980.  
  1981. æKY MidiGetName
  1982. æT Function
  1983. æDT MidiName name= MidiGetName( (short)refNum);
  1984. æC 
  1985.  
  1986. Description
  1987. Gives the name of an application. Knowing an application reference number, it is
  1988. possible to find its name using the MidiGetName function. On the reverse, it is
  1989. also possible to find the reference number of an application via its name using
  1990. the MidiGetNamedAppl function.
  1991.  
  1992. Prototype
  1993. C Mac ANSI    :    pascal MidiName    MidiGetName(short refNum);
  1994. Pascal Mac    :           Function    MidiGetName (refNum: integer) : MidiName;
  1995.  
  1996. Arguments
  1997. refNum :     a 16-bit integer, the reference number of the application
  1998.  
  1999. Result
  2000. The result is pointer on a character string representing the application name.
  2001.  
  2002. Example (ANSI C)
  2003. Print the name of all the active MidiShare applications
  2004.  
  2005. void PrintApplNames(void)
  2006. {
  2007.     short     ref;
  2008.     short     i;
  2009.     
  2010.     printf( "List of MidiShare applications :\n" );
  2011.     for( i = 1; i <= MidiCountAppls(); ++i )
  2012.     {
  2013.         ref = MidiGetIndAppl(i);
  2014.         printf("%i : %s \n", ref, MidiGetName( ref ) );
  2015.     }
  2016. }
  2017.  
  2018. Note for Mac users : MidiShare was originaly developed for Pascal on the Macintosh.
  2019. Consequently, in C, the result of MidiGetName is a Pascal string that must be converted
  2020. to a C string before being printed.
  2021.  
  2022. æKY MidiGetNamedAppl
  2023. æT Function
  2024. æDT short myRet= MidiGetNamedAppl( (MidiName)name);
  2025. æC 
  2026.  
  2027. Description
  2028. Gives the reference number of an application. Knowing an application name, it is
  2029. possible to find its reference number using the MidiGetNamedAppl function. On the
  2030. reverse, it is also possible to find the name of an application via its reference
  2031. number using the MidiGetName function.
  2032.  
  2033. Prototype
  2034. C Mac ANSI        pascal short    MidiGetNamedAppl (MidiName name);
  2035. Pascal Mac    :        Function    MidiGetNamedAppl (name: MidiName) : integer;
  2036.  
  2037. Arguments
  2038. name :     the application name.
  2039.  
  2040. Result
  2041. The result is the reference number of the application.
  2042.  
  2043. Example (ANSI C)
  2044. Find the reference number of the "MidiShare" pseudo-application.
  2045.  
  2046. short    r;
  2047.  
  2048. r = MidiGetNamedAppl("MidiShare");/* MidiShare reference is always 0 */
  2049.  
  2050. Note for Mac users : MidiShare was originaly developed for Pascal on the Macintosh.
  2051. Consequently, in C, all strings passed as arguments of a MidiShare function must
  2052. be Pascal strings.  In the previous example, one must write :        MidiGetNamedAppl("\pMidiShare")
  2053.  
  2054. æKY MidiGetPortState
  2055. æT Function
  2056. æDT Boolean myRet= MidiGetPortState( (short)port);
  2057. æC 
  2058.  
  2059. Description
  2060. Gives the Midi port state. The switching on or off of Midi ports is controlled
  2061. by the MidiSetPortState and MidiGetPortState routines. These must be used with
  2062. care since they affect all the applications.
  2063.  
  2064. Prototype
  2065. C Mac ANSI    :    pascal Boolean    MidiGetPortState(short port);
  2066. Pascal Mac    :          Function    MidiGetPortState(port: integer): boolean;
  2067.  
  2068. Arguments
  2069. port :     a port number from 0 to 255.
  2070.  
  2071. Result
  2072. The result is true if the port is open or false if the port is closed.
  2073.  
  2074. Example (ANSI C)
  2075. Print the state of all the Midi ports.
  2076.  
  2077. void PrintPortsState(void)
  2078. {
  2079.     short i;
  2080.     
  2081.     printf( "Midi ports state :\n");
  2082.     for( i = 0; i < 256; ++i )
  2083.     {
  2084.         if ( MidiGetPortState( i ) )
  2085.             printf(" %i is open \n", i );
  2086.         else
  2087.             printf(" %i is closed \n", i );
  2088.     }
  2089. }
  2090.  
  2091. Note : On the Atari, there is just one Midi port (port 0), and on the Macintosh
  2092. there are just two ports (port modem: 0, port printer: 1). But the future Lan version
  2093. of MidiShare will allow up to 256 ports to be used. Therefore, applications must
  2094. consider that 256 ports are available.
  2095.  
  2096. æKY MidiGetRcvAlarm
  2097. æT Function
  2098. æDT RcvAlarmPtr myPtr= MidiGetRcvAlarm( (short)refNum);
  2099. æC 
  2100.  
  2101. Description
  2102. Gives the address of reception alarm of an application.The reception alarm warns
  2103. of the presence of new events in the reception fifo. This alarm is always called
  2104. under interruption. Therefore, it must not make use, either directly or indirectly,
  2105. the Macintosh Memory Manager. On the reverse, it can have a free access to all
  2106. the MidiShare functions (exept MidiOpen and MidiClose), in particular event management.
  2107. It can also use global variables of the application, because, before the call,
  2108. MidiShare restaures the global context register of the application. 
  2109.  
  2110. Prototype
  2111. C Mac ANSI    :    pascal RcvAlarmPtr    MidiGetRcvAlarm(short refNum);
  2112. Pascal Mac    :    function    MidiGetRcvAlarm(refNum:                             integer):RcvAlarmPtr;
  2113.  
  2114. Arguments
  2115. refNum :     a 16-bit integer, the reference number of the application
  2116.  
  2117. Result
  2118. The result, a RcvAlarmPtr, it is the address of the receive alarm routine or NIL
  2119. if no such routine where installed. 
  2120.  
  2121. Prototype of a RcvAlarm routine
  2122. C Mac ANSI    :    pascal void    MyRcvAlarm (short refNum);
  2123. Pascal Mac    :    procedure    MyRcvAlarm (refNum:integer);
  2124.  
  2125. Argument of a RcvAlarm routine
  2126. refNum     : a 16-bit integer, it is the reference number of the application.
  2127.  
  2128. Example (ANSI C)
  2129. Temporarily disable the application receive alarm.
  2130.  
  2131. RcvAlarmPtr p;
  2132. .....
  2133. p = MidiGetRcvAlarm( myRefNum );
  2134. MidiSetRcvAlarm( NIL );        /* Disable application receive alarm    */
  2135. .....
  2136. MidiSetRcvAlarm( p );        /* Restaure application receive alarm    */
  2137.  
  2138. æKY MidiGetSyncInfo
  2139. æT Function
  2140. æDT MidiGetSyncInfo( (SyncInfoPtr)p);
  2141. æC 
  2142.  
  2143. Description
  2144. Fills a TSyncInfo record with informations about the current state of the MTC synchronisation.
  2145.  
  2146. Prototypes
  2147. C Mac ANSI :     pascal void     MidiGetSyncInfo (SyncInfoPtr p);
  2148. Pascal Mac :     PROCEDURE     MidiGetSyncInfo (p: SyncInfoPtr);
  2149.  
  2150. Arguments
  2151. p: a SyncInfoPtr, a pointer to a TSyncInfo record
  2152.  
  2153. description of a TSyncInfo record
  2154. typedef struct TSyncInfo
  2155. {
  2156. long     time;                // the current MidiShare date (in milliseconds)
  2157. long     reenter;            // the current reentrancy count of the interrupt handler
  2158. unsigned short syncMode;    // the current synchronisation mode as defined 
  2159.                                 by MidiSetSyncMode
  2160. Byte    syncLocked;         // the current synchronisation state 
  2161.                                 (0 : unlocked 1 : locked)
  2162. Byte    syncPort;            // the current synchronisation port
  2163. long    syncStart;            // the date MidiShare started beeing locked 
  2164.                                 to external sync (in ms)
  2165. long    syncStop;            // the date MidiShare stopped being locked 
  2166.                                 to external sync (in ms)
  2167. long    syncOffset;            // the current offset (MidiGetExtTime() - MidiGetTime(), in ms)
  2168. long    syncSpeed;            // the current value for the timer (implementation 
  2169.                                 dependent)
  2170. long    syncBreaks;            // the current count of breaks (transition from state 
  2171.                                 locked to unlocked)
  2172. short    syncFormat;            // the current synchronisation format
  2173.                                 (0 : 24 f/s, 1 : 25 f/s, 2 : 30DF f/s, 3 : 30 f/s)
  2174. } TSyncInfo;
  2175.  
  2176. Note 1
  2177. syncMode is an unsigned 16-bits word of struture : xa000000pppppppp. 
  2178. x (bit 15) is used to choose between internal synchronisation (x=0) and external
  2179. synchronisation (x=1) a (bit 14) is used to choose between synchronisation on port
  2180. p (a=0) and synchronisation on any port (a=1) bit 13:8 are reserved for future
  2181. use and must be set to 0. p (bit 0:7) is the synchronisation port to be used when
  2182. x=1 and a=0. When a=1 the port number is ignored, the first port with incomming
  2183. MTC is used.
  2184.  
  2185. Note 2
  2186. While MidiShare is locked (syncLocked == 1) syncOffset is constant and we have
  2187. the following relationships : MidiGetExtTime() == MidiGetTime() + syncOffset
  2188. MidiInt2ExtTime(x) == x + syncOffset
  2189. MidiExt2IntTime(x) == x - syncOffset
  2190.  
  2191. Example (ANSI C)
  2192. Gives the SMPTE start location of the tape.
  2193.  
  2194. TSyncInfo     myInfo;
  2195. TSmpteLocation    myLoc;
  2196. MidiGetSyncInfo(&myInfo);
  2197. MidiTime2Smpte( MidiInt2ExtTime(myInfo.syncStart), myInfo.syncFormat, &myLoc);
  2198.  
  2199. æKY MidiGetTime
  2200. æT Function
  2201. æDT long myRet= MidiGetTime();
  2202. æC 
  2203.  
  2204. Description
  2205. Gives in milliseconds the time past since the starting up of MidiShare.
  2206.  
  2207. Prototype
  2208. C Mac ANSI    :    pascal long    MidiGetTime();
  2209. Pascal Mac    :    Function    MidiGetTime : longint;
  2210.  
  2211. Arguments
  2212. none
  2213.  
  2214. Result
  2215. The result is a 32-bit integer, the elapsed time in milliseconds since the starting
  2216. up of MidiShare. 
  2217.  
  2218. Example (ANSI C)
  2219. A wait function :
  2220.  
  2221. void wait(long delay)
  2222. {
  2223.     long d;
  2224.     
  2225.     d = MidiGetTime() + delay;
  2226.     while (MidiGetTime() < d);
  2227. }
  2228.  
  2229. æKY MidiGetVersion
  2230. æT Function
  2231. æDT short myRet= MidiGetVersion();
  2232. æC 
  2233.  
  2234. Description
  2235. Gives the version number of MidiShare
  2236.  
  2237. Prototype
  2238. C Mac ANSI    :    pascal short    MidiGetVersion(void);
  2239. Pascal Mac    :     Function    MidiGetVersion : integer;       
  2240.  
  2241. Arguments
  2242. none
  2243.  
  2244. Result
  2245. The result is a 16-bit integer, the MidiShare version number. A result of 161 means
  2246. <version 1.61>. 
  2247.  
  2248. Example (ANSI C)
  2249. Print the MidiShare version number
  2250.  
  2251. void PrintVersion(void)
  2252. {
  2253.     printf( "MidiShare version : %4.2f\n", MidiGetVersion()/100.0);
  2254. }
  2255.  
  2256. æKY MidiGrowSpace
  2257. æT Function
  2258. æDT long myRet= MidiGrowSpace( (long)n);
  2259. æC 
  2260.  
  2261. Description
  2262. Try to increase the memory space of MidiShare.
  2263.  
  2264. Prototype
  2265. C Mac ANSI    :    pascal long    MidiGrowSpace(long n);
  2266. Pascal Mac    :     Function    MidiGrowSpace(n : longint): longint;       
  2267.  
  2268. Arguments
  2269. n : the number of cells to increase the MidiShare memory space.
  2270.  
  2271. Result
  2272. The result is a 32-bit integer, the number of new cells actually allocated. 
  2273.  
  2274. Example (ANSI C)
  2275. Add 1000 cells to MidiShare memory space.
  2276.  
  2277. void TryGrowSpace(void)
  2278. {
  2279.     printf( "Try to allocate 1000 cells : %ld\n", MidiGrowSpace(1000));
  2280. }
  2281.  
  2282.  
  2283. æKY MidiInt2ExtTime
  2284. æT Function
  2285. æDT long  myRet= MidiInt2ExtTime( (long)time)
  2286. æC 
  2287.  
  2288. Description
  2289. Convert an internal time in millisecond to an external time. The convertion is
  2290. made by adding the current offset between internal and external time.
  2291.  
  2292. Prototypes
  2293. C Mac ANSI :     pascal long     MidiInt2ExtTime (long time)
  2294. Pascal Mac :     FUNCTION     MidiGetExtTime (time : longint) : longint;
  2295.  
  2296. Arguments
  2297. time : a 32-bits time in milliseconds
  2298.  
  2299. Result
  2300. the corresponding external time, a 32-bits value in milliseconds.
  2301.  
  2302. Note
  2303. When MidiShare is locked we have the following equivalence :
  2304.  
  2305. MidiInt2ExtTime( MidiGetTime() ) == MidiGetExtTime()
  2306.  
  2307. We have also :
  2308.  
  2309. TSyncInfo     myInfo;
  2310. MidiGetSyncInfo(&myInfo);
  2311. MidiInt2ExtTime(x) == x + myInfo.syncOffset
  2312.  
  2313. æKY MidiIsConnected
  2314. æT Function
  2315. æDT Boolean myRet= MidiIsConnected( (short)src, (short)dest );
  2316. æC 
  2317.  
  2318. Description
  2319. Gives the state of a connection between two MidiShare applications. Connections
  2320. allow real-time communications of midi events between applications.
  2321.  
  2322. Prototype
  2323. C Mac ANSI    :    pascal Boolean    MidiIsConnected( short src, short dest );
  2324. Pascal Mac    :     Function    MidiIsConnected( src, dest: integer) : boolean;
  2325.  
  2326. Arguments
  2327. src :         is the reference number of a source application
  2328. dest :     is the reference number of a destination application
  2329.  
  2330. Result
  2331. The result is true when a connection exist between the source and the destination,
  2332. and false otherwise. 
  2333.  
  2334. Example (ANSI C)
  2335. Print all the sources of an application
  2336.  
  2337. void PrintSources(short refNum)
  2338. {
  2339.     short     src;
  2340.     short     i;
  2341.     
  2342.     printf( "Sources of : %s\n", MidiGetName( refNum) );
  2343.     for( i = 1; i <= MidiCountAppls(); ++i )
  2344.     {
  2345.         src = MidiGetIndAppl(i);
  2346.         if ( MidiIsConnected(src, refNum) )
  2347.             printf(" %i : %s \n", src, MidiGetName( src ) );
  2348.     }
  2349. }
  2350.  
  2351. Note for Mac users : MidiShare was originaly developed for Pascal on the Macintosh.
  2352. Consequently, the result of MidiGetName is a Pascal string that must be converted
  2353. to a C string to be printed.
  2354.  
  2355. æKY MidiNewCell
  2356. æT Function
  2357. æDT MidiEvPtr myPtr= MidiNewCell();
  2358. æC 
  2359.  
  2360. Description
  2361. Allocates a simple memory cell from the MidiShare memory manager. For some special
  2362. treatments, it may be useful to have access to the basic functions of the memory
  2363. manager. All the events managed by MidiShare are implemented from fixed-sized cells
  2364. (16 bytes).
  2365.  
  2366. Prototype
  2367. C Mac ANSI    :    pascal MidiEvPtr    MidiNewCell(void);
  2368. Pascal Mac    :     Function    MidiNewCell : MidiEvPtr;  
  2369.  
  2370. Arguments
  2371. none
  2372.  
  2373. Result
  2374. The result a MidiEvPtr, a pointer to a memory cell, or NIL when memory space is
  2375. exhausted. 
  2376.  
  2377. Example (ANSI C)
  2378. Allocate a new cell.
  2379.  
  2380. MidiEvPtr c;
  2381.  
  2382. c = MidiNewCell();
  2383.  
  2384. .....
  2385.  
  2386. MidiFreeCell(c);
  2387.  
  2388. Note : Cells allocated with MidiNewCell must be freed with MidiFreeCell and not
  2389. with MidiFreeEv.
  2390.  
  2391. æKY MidiNewEv
  2392. æT Function
  2393. æDT MidiEvPtr myPtr= MidiNewEv( (short)typeNum );
  2394. æC 
  2395.  
  2396. Description
  2397. Allocates a new event of desirable type.
  2398.  
  2399. Prototype
  2400. C Mac ANSI    :    pascal MidiEvPtr    MidiNewEv( short typeNum );
  2401. Pascal Mac    :            Function    MidiNewEv(typeNum: integer): MidiEvPtr;
  2402.  
  2403. Arguments
  2404. typeNum :     the type of event to be allocated
  2405.  
  2406. Result
  2407. The result a MidiEvPtr, a pointer to a MidiShare event of the desired type, or
  2408. NIL if the MidiShare memory space is exhausted.
  2409.  
  2410. Example (ANSI C)
  2411. A function for creating note events.
  2412.  
  2413.  
  2414. MidiEvPtr Note(long date, short pitch, short vel,
  2415.               long dur, short chan, short port)
  2416. {
  2417.     MidiEvPtr e;
  2418.     
  2419.     if ( e=MidiNewEv(typeNote) )
  2420.     {
  2421.         Date(e) = date; Pitch(e) = pitch; Vel(e) = vel;
  2422.         Dur(e) = dur; Chan(e) = chan; Port(e) = port;
  2423.     }
  2424.     return e;
  2425. }
  2426.  
  2427. æKY MidiNewSeq
  2428. æT Function
  2429. æDT MidiSeqPtr myPtr= MidiNewSeq();
  2430. æC 
  2431.  
  2432. Description
  2433. Allocation of a new empty sequence.
  2434.  
  2435. Prototype
  2436. C Mac ANSI    :    pascal MidiSeqPtr    MidiNewSeq();
  2437. Pascal Mac    :    Function    MidiNewSeq : MidiSeqPtr; 
  2438.  
  2439. Arguments
  2440. none
  2441.  
  2442. Result
  2443. The result is a MidiSeqPtr, a pointer to an empty sequence. 
  2444.  
  2445.  
  2446. Example (ANSI C)
  2447. Create a sequence of 10 Midi clocks.
  2448.  
  2449. MidiSeqPtr ClockSeq()
  2450. {
  2451.     MidiSeqPtr    s;
  2452.     MidiEvPtr    e;
  2453.     long    d;
  2454.     
  2455.     s = MidiNewSeq();
  2456.     for (d=0; d< 2500; d+=250) 
  2457.     {
  2458.         e = MidiNewEv (typeClock);
  2459.         Date(e) = d;
  2460.         MidiAddSeq (s, e);
  2461.     }
  2462.     return s;
  2463. }
  2464.  
  2465. æKY MidiOpen
  2466. æT Function
  2467. æDT short myRet= MidiOpen( (MidiName)applName );
  2468. æC 
  2469.  
  2470. Description
  2471. Opening of MidiShare. MidiOpen allows the recording of some information relative
  2472. to the application context (its name, the value of the global data register, etc...),
  2473. to allocate a reception FIFO and to attribute a unique reference number to the
  2474. application. In counterpart to any MidiOpen call, the application must call the
  2475. MidiClose function before leaving, by giving its reference number as an argument.
  2476. MidiShare can thus be aware of the precise number of active Midi applications.
  2477.  
  2478.  
  2479. Prototype
  2480. C Mac ANSI    :    pascal short    MidiOpen( MidiName applName );
  2481. Pascal Mac    :        Function    MidiOpen( applName: midiName ): integer;
  2482.  
  2483. Arguments
  2484. applName :     the name of the application.
  2485.  
  2486. Result
  2487. The result is a unique reference number identifing the application. 
  2488.  
  2489. Example (ANSI C)
  2490. A DoNothing MidiShare application.
  2491.  
  2492. #include MidiShare.h
  2493. #include <stdio.h>
  2494.  
  2495. short    myRefNum;
  2496.  
  2497. main()
  2498. {
  2499.     if ( ! MidiShare() )     exit(1);         /* Check MidiShare loaded    */
  2500.     myRefNum = MidiOpen("Sample");    /* Ask for a reference number    */
  2501.     if ( myRefNum < 1 )     exit(1);        /* Check MidiOpen success    */
  2502.     printf( "refNum : %i \n", myRefNum);/* Print the reference number*/
  2503.     MidiClose(myRefNum);                /* And close                */
  2504. }
  2505.  
  2506. Note for Mac users : MidiShare was originaly developed for Pascal on the Macintosh.
  2507. Consequently, in C, all strings passed as arguments of a MidiShare function must
  2508. be Pascal strings. In the previous exemple, one must write :          myRefNum = MidiOpen("\pSample");
  2509.  
  2510. æKY MidiReadSync
  2511. æT Function
  2512. æDT void* myPtr= MidiReadSync( (void* )adrMem) ;
  2513. æC 
  2514.  
  2515. Description
  2516. The MidiReadSync function reads and sets to NIL a memory address. This function
  2517. is none-interruptible in order to make easier communication between the application
  2518. tasks that run at interrupt level. It can be used to implement some sort of "mail
  2519. boxes" in conjunction of MidiWriteSync.
  2520.  
  2521. Prototype
  2522. C Mac ANSI    :    pascal void*    MidiReadSync( void* adrMem) ;
  2523. Pascal Mac    :        Function    MidiReadSync( adrMem: univ ptr): ptr;
  2524.  
  2525. Arguments
  2526. adrMem :     the address of a variable containing a 32-bit data.
  2527.  
  2528. Result
  2529. The result is the content of the variable. 
  2530.  
  2531. Side effect
  2532. Once read, the content of the variable is set to NIL. 
  2533.  
  2534. Example (ANSI C)
  2535. << to be supplied >>
  2536.  
  2537. æKY MidiSend
  2538. æT Function
  2539. æDT MidiSend( (short)refNum, (MidiEvPtr)e );
  2540. æC 
  2541.  
  2542. Description
  2543. Sends an event. A copy of the event is sended to all the application destinations.
  2544. The date field of the event is used to specify when destinations will actually
  2545. receive the event.
  2546.  
  2547. Prototype
  2548. C Mac ANSI    :    pascal void    MidiSend( short refNum, MidiEvPtr e );
  2549. Pascal Mac    :    procedure    MidiSend( refNum: integer; e : MidiEvPtr);
  2550.  
  2551. Arguments
  2552. refNum     : a 16-bit integer, it is the reference number of the application.
  2553. e         : a MidiEvePtr, it is a pointer to the event to send.
  2554.  
  2555. Example (ANSI C)
  2556. A receive alarm that processes all the received events by adding a one second delay
  2557. to their date.
  2558.  
  2559. void OneSecDelay (short refNum)
  2560. {
  2561.     MidiEvPtr    e;
  2562.     long n;
  2563.  
  2564.     for ( n = MidiCountEvs(refNum); n > 0; —n ) 
  2565.     {                                
  2566.         e = MidiGetEv(refNum);    /* Get an event from the fifo        */
  2567.         Date(e) += 1000;        /* Add 1000 ms to its date        */
  2568.         MidiSend(refNum,e);        /* Then send the event            */
  2569.     }
  2570. }
  2571. ......
  2572. MidiSetRcvAlarm(myRefNum,OneSecDelay);    /* Activate the receive alarm*/
  2573.  
  2574. Note : such a procedure can be called repeatedly in the main event loop of the
  2575. application, but for really accurate time control, it must be installed as a receive
  2576. alarm with MidiSetRcvAlarm.
  2577.  
  2578. Note for Mac users : MidiShare was originaly developed for Pascal on the Macintosh.
  2579. Consequently, in C, all procedure passed as arguments of a MidiShare function must
  2580. be declared as Pascal. In the previous exemple, OneSecDelay must be declared as
  2581. :          pascal void OneSecDelay (short refNum)
  2582.  
  2583. æKY MidiSendAt
  2584. æT Function
  2585. æDT MidiSendAt( (short)refNum, (MidiEvPtr)e, (long)d );
  2586. æC 
  2587.  
  2588. Description
  2589. Sends an event. A copy of the event is sended to all the application destinations.
  2590. The date argument is used to specify when destinations will actually receive the
  2591. event.
  2592.  
  2593. Prototype
  2594. C Mac ANSI    :    pascal void    MidiSendAt( short refNum, MidiEvPtr e, long d );
  2595. Pascal Mac    :    procedure    MidiSendAt( refNum:integer; e:MidiEvPtr; d:longint);
  2596.  
  2597. Arguments
  2598. refNum     : a 16-bit integer, it is the reference number of the application.
  2599. e         : a MidiEvePtr, it is a pointer to the event to send.
  2600. d         : a 32-bit integer, the date when destinations will receive the event.
  2601.  
  2602. Example (ANSI C)
  2603. Equivalence between MidiSend, MidiSendAt and MidiSendIm :
  2604.  
  2605. MidiSendAt(myRefNum,e,MidiGetTime());
  2606.  
  2607.     is equivalent to :
  2608.  
  2609. MidiSendIm(myRefNum,e);
  2610.  
  2611.     is equivalent to :
  2612.  
  2613. Date(e) = MidiGetTime();
  2614. MidiSend( myRefNum, e );
  2615.  
  2616. æKY MidiSendIm
  2617. æT Function
  2618. æDT MidiSendIm( (short)refNum, (MidiEvPtr)e );
  2619. æC 
  2620.  
  2621. Description
  2622. Immediatly sends an event. A copy of the event is sended to all the application
  2623. destinations.
  2624.  
  2625. Prototype
  2626. C Mac ANSI    :    pascal void    MidiSendIm( short refNum, MidiEvPtr e );
  2627. Pascal Mac    :    procedure    MidiSendIm( refNum:integer; e:MidiEvPtr );
  2628.  
  2629. Arguments
  2630. refNum     : a 16-bit integer, it is the reference number of the application.
  2631. e         : a MidiEvePtr, it is a pointer to the event to send.
  2632.  
  2633. Example (ANSI C)
  2634. equivalence between MidiSend, MidiSendAt and MidiSendIm :
  2635.  
  2636. MidiSendIm(myRefNum,e);
  2637.  
  2638.     is equivalent to :
  2639.  
  2640. MidiSendAt(myRefNum,e,MidiGetTime());
  2641.  
  2642.     is equivalent to :
  2643.  
  2644. Date(e) = MidiGetTime();
  2645. MidiSend( myRefNum, e );
  2646.  
  2647. æKY MidiSetApplAlarm
  2648. æT Function
  2649. æDT MidiSetApplAlarm(short refNum, ApplAlarmPtr 
  2650. æC 
  2651.  
  2652. Description
  2653. Defines the context alarm of an application. These alarm will be called by MidiShare
  2654. on every application global context modifications (opening and closing of applications,
  2655. opening and closing of midi ports, changes in connections between applications,
  2656. SMPTE synchronisation).
  2657.  
  2658. Prototype
  2659.             alarm);
  2660. C Mac ANSI    :    pascal void    MidiSetApplAlarm(short refNum, ApplAlarmPtr 
  2661.             alarm);
  2662. Pascal Mac    :    Procedure    MidiSetApplAlarm(refNum:integer; 
  2663.             alarm:ApplAlarmPtr);  
  2664.  
  2665. Arguments
  2666. refNum :     a 16-bit integer, it is the reference number of the application.
  2667. alarm:     a ApplAlarmPtr, a  pointer to the application context alarm routine.
  2668.  
  2669. Prototype of a ApplAlarm routine
  2670. C Mac ANSI    :    pascal void    MyApplAlarm (short refNum, long code);
  2671. Pascal Mac    :    procedure    MyApplAlarm (refNum:integer; code:longint);
  2672.  
  2673. Argument of a ApplAlarm routine
  2674. refNum     : a 16-bit integer, it is the reference number of the application.
  2675. code     : a 32-bit integer, the context modification code : 0xRRRRMMMM where RRRR
  2676. is the Reference number of the involved application and MMMM the type of change
  2677. (see Midi Change Codes). 
  2678.  
  2679. Example (ANSI C)
  2680. << to be supplied >>
  2681.  
  2682. æKY MidiSetField
  2683. æT Function
  2684. æDT MidiSetField( (MidiEvPtr)e, (long)f, (long)v );
  2685. æC 
  2686.  
  2687. Description
  2688. Attributes a value to the i index data field of an event. The access to the compulsory
  2689. fields of the event is directly done. But the access to the variables fields is
  2690. achieved thru the MidiSetField and MidiGetField functions.  The procedure deals
  2691. with the conversion of this value into the concerned field format (8, 16 or 32-bit).
  2692.  
  2693. Prototype
  2694. C Mac ANSI    :    pascal void    MidiSetField( MidiEvPtr e, long f, long v );
  2695. Pascal Mac    :    procedure    MidiSetField( e:MidiEvPtr; f:longint; 
  2696.             v:longint );
  2697.  
  2698. Arguments
  2699. e :     a MidiEvPtr, a pointer to the event to modifie
  2700. f :     a 32-bit integer, the index number of the field to modify 
  2701.         ( from 0 to MidiCountFields(e)-1) 
  2702. v :     a 32-bit value to put in the field. This value will be converted to the
  2703.         right size (8, 16 or 32-bit)
  2704.  
  2705. Example (ANSI C)
  2706. << to be supplied >>
  2707.  
  2708. æKY MidiSetFilter
  2709. æT Function
  2710. æDT MidiSetFilter( (short)refNum, (FilterPtr)filter );
  2711. æC 
  2712.  
  2713. Description
  2714. Associates a filter to an application. Each application can select the events to
  2715. be received by using a filter. The filtering process is local to the application
  2716. and has no influence on the events received by the other applications. The implementation
  2717. of these filters is achieved by two routines : MidiSetFilter and MidiGetFilter.
  2718.  
  2719. Prototype
  2720. C Mac ANSI    :    pascal void    MidiSetFilter( short refNum, FilterPtr filter );
  2721. Pascal Mac    :    procedure    MidiSetFilter( refNum: integer; filter: FilterPtr );   
  2722.  
  2723. Arguments
  2724. refNum     : a 16-bit integer, it is the reference number of the application.
  2725. filter     : a FilterPtr, a pointer to the application filter. 
  2726.  
  2727. Example (ANSI C)
  2728. << to be supplied >>
  2729.  
  2730. æKY MidiSetInfo
  2731. æT Function
  2732. æDT MidiSetInfo( short refNum, void* infoZone );
  2733. æC 
  2734.  
  2735. Description
  2736. Defines the global information area of an application. The Macintosh desk accessories
  2737. cannot have global variables. To make up for this drawback, the MidiSetInfo routine
  2738. allows each application to define a data area. This area remains accessible by
  2739. MidiGetInfo function, even during the alarm, and also serves as a global context
  2740. to desk accessories.
  2741.  
  2742. Prototype
  2743. C Mac ANSI    :    pascal void    MidiSetInfo( short refNum, void* infoZone );
  2744. Pascal Mac    :    procedure    MidiSetInfo( refNum: integer; infoZone: Ptr );   
  2745.  
  2746. Arguments
  2747. refNum     : a 16-bit integer, it is the reference number of the application.
  2748. infoZone     : an arbitrary 32-bit value, generaly a pointer or a handle. 
  2749.  
  2750. Example (ANSI C)
  2751. << to be supplied >>
  2752.  
  2753. æKY MidiSetName
  2754. æT Function
  2755. æDT MidiSetName( (short)refNum, (MidiName)name );
  2756. æC 
  2757.  
  2758. Description
  2759. Changes the name of an application.
  2760.  
  2761. Prototype
  2762. C Mac ANSI    :    pascal void    MidiSetName( short refNum, MidiName name );
  2763. Pascal Mac    :    procedure    MidiSetName( refNum: integer; name: midiName);   
  2764.  
  2765. Arguments
  2766. refNum     : a 16-bit integer, it is the reference number of the application.
  2767. name     : a MidiName, the new application name.
  2768.  
  2769. Example (ANSI C)
  2770. << to be supplied >>
  2771.  
  2772. æKY MidiSetPortState
  2773. æT Function
  2774. æDT MidiSetPortState( (short)port, (Boolean)state );
  2775. æC 
  2776.  
  2777. Description
  2778. Opening and closing of a Midi port. The implementation of Midi ports is controlled
  2779. by the MidiSetPortState and MidiGetPortState routines. These must be used with
  2780. care since they affect all the applications.  A closed port is available for other
  2781. uses (printing, AppleTalk, etc...). The Midi applications holding a "context alarm"
  2782. will be informed of this change in the ports state.
  2783.  
  2784. Prototype
  2785. C Mac ANSI    :    pascal void    MidiSetPortState( short port, Boolean state );
  2786. Pascal Mac    :    procedure    MidiSetPortState( port: integer;
  2787.             state: boolean );   
  2788.  
  2789. Arguments
  2790. port :     a 16-bit integer, the port number to control.
  2791. state :     a Boolean, True : to open a port, False : to close a port.
  2792.  
  2793. Example (ANSI C)
  2794. << to be supplied >>
  2795.  
  2796. æKY MidiSetRcvAlarm
  2797. æT Function
  2798. æDT MidiSetRcvAlarm( short refNum, RcvAlarmPtr alarm );
  2799. æC 
  2800.  
  2801. Description
  2802. Defines the event reception alarm of an application. The alarm will be automatically
  2803. called by MidiShare to inform the application of the presence of new events in
  2804. its reception fifo. This alarm is always called under interruption. It must not
  2805. use, directly or indirectly, the Macintosh Memory Manager. It can freely access
  2806. to all the others MidiShare functions, particularly to the event management (but
  2807. not MidiOpen and MidiClose). It can also use application global variables, since
  2808. MidiShare restaures its global context register, before the call.
  2809.  
  2810. Prototype of MidiSetRcvAlarm
  2811. C Mac ANSI    :    pascal void    MidiSetRcvAlarm( short refNum, RcvAlarmPtr alarm );
  2812. Pascal Mac    :     Procedure    MidiSetRcvAlarm(refNum:integer; alarm:RcvAlarmPtr );  
  2813.  
  2814. Arguments of MidiSetRcvAlarm
  2815. refNum :     a 16-bit integer, the reference number of the application
  2816. alarm :     a RcvAlarmPtr, a pointer to a receive alarm routine or NIL to disable
  2817. receive alarms.
  2818.  
  2819. Prototype of a RcvAlarm routine
  2820. C Mac ANSI    :    pascal void    MyRcvAlarm (short refNum);
  2821. Pascal Mac    :    procedure    MyRcvAlarm (refNum:integer);
  2822.  
  2823. Argument of a RcvAlarm routine
  2824. refNum     : a 16-bit integer, it is the reference number of the application.
  2825.  
  2826. Example (ANSI C)
  2827. A receive alarm that processes all the received events by adding to their date
  2828. a one second delay.
  2829.  
  2830. void OneSecDelay (short refNum)
  2831. {
  2832.     MidiEvPtr    e;
  2833.     long n;
  2834.  
  2835.     for ( n = MidiCountEvs(refNum); n > 0; —n ) 
  2836.     {                                
  2837.         e = MidiGetEv(refNum);/* Get an event from the fifo        */
  2838.         Date(e) += 1000;        /* Add 1000 ms to its date        */
  2839.         MidiSend(refNum,e);        /* Then send the event            */
  2840.     }
  2841. }
  2842.  
  2843. ......
  2844.  
  2845. MidiSetRcvAlarm(myRefNum,OneSecDelay);    /* Install the receive alarm*/
  2846.  
  2847. Note : one such procedure can be called repeatedly in the main event loop of the
  2848. application, but for really accurate time control, it must be installed as a receive
  2849. alarm with MidiSetRcvAlarm.
  2850.  
  2851. Note for Mac users : MidiShare was originaly developed for Pascal on the Macintosh.
  2852. Consequently, in C, all procedure passed as arguments of a MidiShare function must
  2853. be declared as Pascal. In the previous exemple, OneSecDelay must be declared as
  2854. :          pascal void OneSecDelay (short refNum)
  2855.  
  2856. æKY MidiSetSyncMode
  2857. æT Function
  2858. æDT MidiSetSyncMode( (unsigned)short mode);
  2859. æC 
  2860.  
  2861. Description
  2862. Set the synchronisation mode of MidiShare.
  2863.  
  2864. Prototypes
  2865. C Mac ANSI :     pascal void     MidiSetSyncMode (unsigned short mode);
  2866. Pascal Mac :     PROCEDURE     MidiSetSyncMode (mode: integer);
  2867.  
  2868. Arguments
  2869. mode : an unsigned 16-bits word of struture : xa000000pppppppp. 
  2870. x (bit 15) is used to choose between internal synchronisation (x=0) and external
  2871. synchronisation (x=1) a (bit 14) is used to choose between synchronisation on port
  2872. p (a=0) and synchronisation on any port (a=1) bit 13:8 are reserved for future
  2873. use and must be set to 0. p (bit 0:7) is the synchronisation port to be used when
  2874. x=1 and a=0. When a=1 the port number is ignored, the first port with incomming
  2875. MTC is used.
  2876.  
  2877. Example 1 (ANSI C)
  2878. Set the synchronisation to external, on any port.
  2879.  
  2880. MidiSetSyncMode(MIDISyncExternal | MIDISyncAnyPort);
  2881.  
  2882. Example 2 (ANSI C)
  2883. Set the synchronisation to external, on port 18.
  2884.  
  2885. MidiSetSyncMode(MIDISyncExternal | 18);
  2886.  
  2887. Example 3 (ANSI C)
  2888. Set the synchronisation to internal.
  2889.  
  2890. MidiSetSyncMode(MIDISyncInternal);
  2891.  
  2892. æKY MidiShare
  2893. æT Function
  2894. æDT Boolean myRet= MidiShare();
  2895. æC 
  2896.  
  2897. Description
  2898. Tests MidiShare code presence in memory by trying to recognise a special pattern.
  2899. First of all, an application must make sure that MidiShare is in memory. This test
  2900. is done thanks to the MidiShare function.
  2901.  
  2902. Prototype
  2903. C Mac ANSI    :    pascal Boolean    MidiShare(void);
  2904. Pascal Mac    :          Function    MidiShare : boolean;
  2905.  
  2906. Arguments
  2907. none
  2908.  
  2909. Result
  2910. The result is true when MidiShare is loaded, false otherwise. 
  2911.  
  2912. Example (ANSI C)
  2913. A DoNothing MidiShare application.
  2914.  
  2915. #include MidiShare.h
  2916. #include <stdio.h>
  2917.  
  2918. short    myRefNum;
  2919.  
  2920. main()
  2921. {
  2922.     if ( ! MidiShare() )     exit(1);        /* Check MidiShare loaded    */
  2923.     myRefNum = MidiOpen("Sample");    /* Ask for a reference number    */
  2924.     if ( myRefNum < 1 )     exit(1);        /* Check MidiOpen success    */
  2925.     printf( "refNum : %i \n", myRefNum);/* Print the reference number*/
  2926.     MidiClose(myRefNum);                /* And close                */
  2927. }
  2928.  
  2929. Note for Mac users : MidiShare was originaly developed for Pascal on the Macintosh.
  2930. Consequently, in C, all strings passed as arguments of a MidiShare function must
  2931. be Pascal strings. In the previous exemple, one must write :          myRefNum = MidiOpen("\pSample");
  2932.  
  2933. æKY MidiSmpte2Time
  2934. æT Function
  2935. æDT long  myRet= MidiSmpte2Time( (SmpteLocPtr)loc);
  2936. æC 
  2937.  
  2938. Description
  2939. Convert an SMPTE location to a time in millisecond.
  2940.  
  2941. Prototypes
  2942. C Mac ANSI :     pascal long     MidiSmpte2Time (SmpteLocPtr loc);
  2943. Pascal Mac :     FUNCTION     MidiSmpte2Time (loc: SmpteLocPtr): longint;
  2944.  
  2945. Arguments
  2946. loc : a pointer to a TSmpteLocation record to be converted in milliseconds.
  2947.  
  2948. Result
  2949. a 32-bits time in milliseconds
  2950.  
  2951. Description of a TSmpteLocation
  2952. typedef struct TSmpteLocation *SmpteLocPtr;
  2953. typedef struct TSmpteLocation
  2954. {
  2955.      short    format;        // (0 : 24 f/s, 1 : 25 f/s, 
  2956.                     2 : 30DF f/s, 3 : 30 f/s)
  2957.      short    hours;        // 0..23
  2958.      short    minutes;        // 0..59
  2959.      short    seconds;        // 0..59
  2960.      short    frames;        // 0..30 (according to format)
  2961.      short    fracs;        // 0..99 (1/100 of frames)
  2962. } TSmpteLocation; 
  2963.  
  2964. Example (ANSI C)
  2965. Gives the SMPTE location from its current format to 30 drop frame (format 2).
  2966. TSmpteLocation    myLoc; 
  2967. ...
  2968. // we suppose here myLoc filled with an Smpte location
  2969.  
  2970. MidiTime2Smpte( MidiSmpte2Time(&myLoc), 2, &myLoc);
  2971.  
  2972. // now myLoc is filled with the same Smpte location but in 30 drop frame format.
  2973.  
  2974. æKY MidiTask
  2975. æT Function
  2976. æDT MidiEvPtr myPtr= MidiTask(TaskPtr MyProc, long date, short refNum, long a1, long a2, long a3); 
  2977. æC 
  2978.  
  2979. Description
  2980. On the same way as MidiDTask, MidiTask allows to realize a time delayed procedure
  2981. call ; but on the reverse to MidiDTask, the call is achieved under interruption
  2982. as soon as falling time is due. 
  2983.  
  2984. Prototype of MidiTask
  2985. C Mac ANSI    :    pascal MidiEvPtr    MidiTask (TaskPtr MyProc, long date, 
  2986.                     short refNum, long a1, long a2, long a3);
  2987. Pascal Mac    :            Function    MidiTask (MyProc:TaskPtr; date:longint; 
  2988.                     refNum:integer; a1,a2,a3: longint):MidiEvPtr;  
  2989.  
  2990. Arguments of MidiTask
  2991. MyProc     : a TaskPtr, it is the address of the routine to be called.
  2992. date     : a 32-bit integer, it is the date at which this call is scheduled. 
  2993. refNum     : a 16-bit integer, it is the reference number of the application.
  2994. a1,a2,a3     : are 32-bit integers left at the user’s disposal, as arguments to MyProc
  2995.  
  2996. Result of MidiTask
  2997. The result, a MidiEvPtr, is a pointer to a typeProcess MidiShare event. The result
  2998. is NIL if MidiShare run out of memory.
  2999.  
  3000. Prototype of MyProc
  3001. C Mac ANSI    :    pascal void    MyProc (long date, short refNum, 
  3002.                             long a1, long a2, long a3);
  3003. Pascal Mac    :    procedure    MyProc (date:longint; refNum:integer; 
  3004.                             a1,a2,a3: longint);
  3005.  
  3006. Argument of MyProc
  3007. date     : a 32-bit integer, it is the date of the call . 
  3008. refNum     : a 16-bit integer, it is the reference number of the application.
  3009. a1,a2,a3     : are 32-bit integers that can be freely used.
  3010.  
  3011. Example (ANSI C)
  3012. Schedule a procedure Action() call 1000 ms ahead.
  3013.  
  3014. MidiEvPtr    myTask;
  3015.  
  3016. myTask = MidiTask(Action,MidiGetTime()+1000,myRefNum, a1, a2, a3);
  3017.  
  3018. Note : The result, in myTask, can be used to test the success of MidiTask. It can
  3019. also be used by MidiForgetTask to try to "forget" a scheduled task before it happens.
  3020.  
  3021. æKY MidiTime2Smpte
  3022. æT Function
  3023. æDT MidiTime2Smpte(long time, 
  3024. æC 
  3025.  
  3026. Description
  3027. Convert a time in millisecond to an SMPTE location.
  3028.  
  3029. Prototypes
  3030. C Mac ANSI :     pascal     void MidiTime2Smpte (long time, 
  3031.             short format, SmpteLocPtr loc);
  3032. Pascal Mac :     PROCEDURE     MidiTime2Smpte (time: longint; 
  3033.             format: integer; loc: SmpteLocPtr);
  3034.  
  3035. Arguments
  3036. time : a 32-bits time in milliseconds to convert in an Smpte location
  3037. format : a 16-bits integer, the Smpte format to be used : (0 : 24 f/s, 1 : 25 f/s,
  3038. 2 : 30DF f/s, 3 : 30 f/s) loc : a pointer to a TSmpteLocation record to be filled
  3039. with the resulting Smpte location.
  3040.  
  3041. Description of a TSmpteLocation
  3042. typedef struct TSmpteLocation *SmpteLocPtr;
  3043. typedef struct TSmpteLocation
  3044. {
  3045.      short    format;    // (0 : 24 f/s, 1 : 25 f/s, 
  3046.                 2 : 30DF f/s, 3 : 30 f/s)
  3047.      short    hours;    // 0..23
  3048.      short    minutes;    // 0..59
  3049.      short    seconds;    // 0..59
  3050.      short    frames;    // 0..30 (according to format)
  3051.      short    fracs;    // 0..99 (1/100 of frames)
  3052. } TSmpteLocation; 
  3053.  
  3054. Example (ANSI C)
  3055. Gives the SMPTE start location of the tape.
  3056.  
  3057. TSyncInfo     myInfo;
  3058. TSmpteLocation    myLoc;
  3059.  
  3060. MidiGetSyncInfo(&myInfo);
  3061. MidiTime2Smpte( MidiInt2ExtTime(myInfo.syncStart), myInfo.syncFormat, 
  3062. &myLoc);
  3063.  
  3064. æKY MidiTotalSpace
  3065. æT Function
  3066. æDT long myRet= MidiTotalSpace();
  3067. æC 
  3068.  
  3069. Description
  3070. Gives the total space. MidiTotalSpace allows to know at any time the total number
  3071. of cells allocated by the MidiShare memory manager at startup.  
  3072.  
  3073. Prototype
  3074. C Mac ANSI    :    pascal long    MidiTotalSpace(void);
  3075. Pascal Mac    :       Function    MidiTotalSpace : longint;
  3076.  
  3077. Arguments
  3078. none
  3079.  
  3080. Result
  3081. the result is a 32-bit integer, the total number of cells in the MidiShare memory
  3082. manager.
  3083.  
  3084. Example (ANSI C)
  3085. Print informations about MidiShare memory space.
  3086.  
  3087. void PrintMemInfo(void)
  3088. {
  3089.     printf("MidiShare memory :\n");
  3090.     printf(" free space  : %i cells\n", MidiFreeSpace());
  3091.     printf(" used space  : %i cells\n", MidiTotalSpace() - MidiFreeSpace());
  3092.     printf(" total space : %i cells\n", MidiTotalSpace());
  3093. }
  3094.  
  3095. æKY MidiWriteSync
  3096. æT Function
  3097. æDT void* myPtr= MidiWriteSync(  (void *)adrMem,  (void *)val );
  3098. æC 
  3099.  
  3100. Description
  3101. Writes a 32-bit value to a variable only if the previous variable content was NIL.
  3102. This function is non-interruptible in order to make easier communication between
  3103. the application tasks that run at interrupt level. It can be used to implement
  3104. some sort of "mail boxes" in conjunction of MidiReadSync
  3105.  
  3106. Prototype
  3107. C Mac ANSI    :    pascal void*    MidiWriteSync( void *adrMem, void *val );
  3108. Pascal Mac    :        Function    MidiWriteSync( adrMem:univ ptr; val:univ ptr):ptr;
  3109.  
  3110. Arguments
  3111. adrMem :     is the addresse of a variable to modifie.
  3112. val :         is a 32-bit value to write.
  3113.  
  3114. Result
  3115. The result is the previous content of the variable. 
  3116.  
  3117. Example (ANSI C)
  3118. << to be supplied >>
  3119.  
  3120. æKY typeActiveSens
  3121. æC 
  3122. typeActiveSens  (code 15)
  3123.  
  3124. Event Description
  3125. A Real Time ActiveSens message. 
  3126.  
  3127.  
  3128. Fields : ActiveSens events have no field.
  3129.  
  3130.  
  3131. Example (ANSI C)
  3132. Creates a ActiveSens event. Return a pointer to the event or NIL if there is no
  3133. more memory space.
  3134.  
  3135. MidiEvPtr ActiveSens ( long date, short port)
  3136. {
  3137.     MidiEvPtr e;
  3138.  
  3139.     if ( e = MidiNewEv( typeActiveSens ) )/* Allocate a new event. Check not NIL*/
  3140.      {
  3141.         Date(e) = date;    /* These informations are common to all*/
  3142.         Port(e) = port;        /* kind of events    */
  3143.     }
  3144.     return e;
  3145. }
  3146.  
  3147. æKY typeChanPress
  3148. æC 
  3149. typeChanPress  (code 6)
  3150.  
  3151. Event Description
  3152. A Channel pressure message with pressure value. 
  3153.  
  3154.  
  3155. Fields : ChanPress events have 1 field numbered 0 :
  3156.  
  3157.     0 - A channel pressure value from 0 to 127. (Field size : 1 byte)
  3158.  
  3159.  
  3160. Example (ANSI C)
  3161. Creates a ChanPress event. Return a pointer to the event or NIL if there is no
  3162. more memory space.
  3163.  
  3164. MidiEvPtr ChanPress( long date, short press, short chan, short port)
  3165. {
  3166.     MidiEvPtr e;
  3167.  
  3168.     if ( e = MidiNewEv( typeChanPress ) )/* Allocate a new event. Check not NIL*/
  3169.      {
  3170.         Date(e) = date;        /* These informations are common to all    */
  3171.         Chan(e) = chan;        /* kind of events                */
  3172.         Port(e) = port;
  3173.         MidiSetField(e,0,press);    /* Field particular to ChanPress    */
  3174.     }
  3175.     return e;
  3176. }
  3177.  
  3178.  
  3179. æKY typeClock
  3180. æC 
  3181. typeClock  (code 10)
  3182.  
  3183. Event Description
  3184. A Real Time Clock message. 
  3185.  
  3186.  
  3187. Fields : Clock events have no field.
  3188.  
  3189.  
  3190. Example (ANSI C)
  3191. Creates a Clock event. Return a pointer to the event or NIL if there is no more
  3192. memory space.
  3193.  
  3194. MidiEvPtr Clock ( long date, short port)
  3195. {
  3196.     MidiEvPtr e;
  3197.  
  3198.     if ( e = MidiNewEv( typeClock ) )/* Allocate a new event. Check not NIL*/ 
  3199.     {
  3200.         Date(e) = date;        /* These informations are common to all    */
  3201.         Port(e) = port;        /* kind of events            */
  3202.     }
  3203.     return e;
  3204. }
  3205. æKY typeContinue
  3206. æC 
  3207. typeContinue  (code 12)
  3208.  
  3209. Event Description
  3210. A Real Time Continue message. 
  3211.  
  3212.  
  3213. Fields : Continue events have no field.
  3214.  
  3215. Example (ANSI C)
  3216. Creates a Continue event. Return a pointer to the event or NIL if there is no more
  3217. memory space.
  3218.  
  3219. MidiEvPtr Continue ( long date, short port)
  3220. {
  3221.     MidiEvPtr e;
  3222.  
  3223.     if ( e = MidiNewEv( typeContinue ) )/* Allocate a new event. Check not NIL*/ 
  3224.     {
  3225.         Date(e) = date;        /* These informations are common to all    */
  3226.         Port(e) = port;        /* kind of events                    */
  3227.     }
  3228.     return e;
  3229. }
  3230.  
  3231. æKY typeCopyrigth
  3232. æC 
  3233. typeCopyrigth  (code 136)
  3234.  
  3235. Event Description
  3236. A copyright event (from the MidiFile 1.0 specification). This event cannot be sent
  3237. to external Midi devices.
  3238.  
  3239.  
  3240. Fields : typeCopyrigth events have a variable number of character fields. 
  3241.  
  3242. Example 1 (ANSI C)
  3243. Creates a typeCopyrigth event from a character string. Return a pointer to the
  3244. event or NIL if there is not enough memory space.
  3245.  
  3246. MidiEvPtr Copyrigth ( long date, char *s, short chan, short port)
  3247. {
  3248.     MidiEvPtr e;
  3249.     long    c=0;
  3250.  
  3251.     if ( e = MidiNewEv(typeCopyrigth) )    /* Allocate a new event.
  3252.                                 Check not NIL    */ 
  3253.     {
  3254.         Date(e) = date;        /* These informations are common to all    */
  3255.         Chan(e) = chan;        /* kind of events        */
  3256.         Port(e) = port;
  3257.         for (c=0; *s; s++, c++)     /* Build the event while counting    */
  3258.             MidiAddField(e ,*s);    /* the characters of 
  3259.                                 the original string        */
  3260.         if (c != MidiCountFields(e)) {    /* Check the length of the event*/
  3261.             MidiFreeEv(e);        /* if we run out of memory : free the    */
  3262.             return 0;            /* event and return NIL        */
  3263.         }
  3264.     }
  3265.     return e;
  3266. }
  3267.  
  3268. Example 2 (ANSI C)
  3269. Convert a typeCopyrigth event into a character string. Assume s big enough.
  3270.  
  3271. void GetText (MidiEvPtr e, char *s)
  3272. {
  3273.     short c=0, i=0;
  3274.     
  3275.     c = MidiCountFields(e);
  3276.     while (i<c) *s++ = MidiGetField(e, i++);
  3277.     *s = 0;
  3278. }
  3279.  
  3280. æKY typeCtrl14b
  3281. æC 
  3282. typeCtrl14b  (code 131)
  3283.  
  3284. Event Description
  3285. A Control Change event with a controller number form 0 to 31 and a 14-bits value.
  3286. When a typeCtrl14b event is sent to external Midi devices, actually two control
  3287. change messages are sent, the first one for the MSB part of the value and the second
  3288. one for the LSB part of the value. The message for the LSB part is sent only when
  3289. the LSB part of the value is different from 0.
  3290.  
  3291.  
  3292. Fields : Ctrl14b events have 2 fields numbered from 0 to 1 :
  3293.  
  3294.     0 - A control number from 0 to 31. (Field size : 2 byte)
  3295.     1 - A control value from 0 to 16383. (Field size : 2 byte)
  3296.  
  3297. Example (ANSI C)
  3298. Creates a CtrlChange event. Return a pointer to the event or NIL if there is no
  3299. more memory space.
  3300.  
  3301. MidiEvPtr CtrlChange14b( long date, short ctrl, short val, short chan, short port)
  3302. {
  3303.     MidiEvPtr e;
  3304.  
  3305.     if ( e = MidiNewEv( typeCtrl14b ) )    /* Allocate a new event. 
  3306.                                 Check not NIL    */ 
  3307.     {
  3308.         Date(e) = date;        /* These informations are common to all    */
  3309.         Chan(e) = chan;        /* kind of events                    */
  3310.         Port(e) = port;
  3311.         MidiSetField(e,0,ctrl);    /* Fields particular to CtrlChange     */
  3312.         MidiSetField(e,1,val);
  3313.     }
  3314.     return e;
  3315. }
  3316.  
  3317. æKY typeCtrlChange
  3318. æC 
  3319. typeCtrlChange  (code 4)
  3320.  
  3321. Event Description
  3322. A Control Change message with controller and value. 
  3323.  
  3324.  
  3325. Fields : CtrlChange events have 2 fields numbered from 0 to 1 :
  3326.  
  3327.     0 - A control number from 0 to 127. (Field size : 1 byte)
  3328.     1 - A control value from 0 to 127. (Field size : 1 byte)
  3329.  
  3330. Example (ANSI C)
  3331. Creates a CtrlChange event. Return a pointer to the event or NIL if there is no
  3332. more memory space.
  3333.  
  3334. MidiEvPtr CtrlChange( long date, short ctrl, short val, short chan, short port)
  3335. {
  3336.     MidiEvPtr e;
  3337.  
  3338.     if ( e = MidiNewEv( typeCtrlChange ) )/* Allocate a new event. 
  3339.                                 Check not NIL    */ 
  3340.     {
  3341.         Date(e) = date;        /* These informations are common to all    */
  3342.         Chan(e) = chan;        /* kind of events        */
  3343.         Port(e) = port;
  3344.         MidiSetField(e,0,ctrl);    /* Fields particular to CtrlChange     */
  3345.         MidiSetField(e,1,val);
  3346.     }
  3347.     return e;
  3348. }
  3349.  
  3350. æKY typeChanPrefix
  3351. æC 
  3352. typeChanPrefix  (code 142)
  3353.  
  3354. Event Description
  3355. A channel prefix event (from the MidiFile 1.0 specification). This event cannot
  3356. be sent to external Midi devices.
  3357.  
  3358.  
  3359. Fields : typeChanPrefix events have one field. 
  3360.  
  3361.     0 - A channel prefix number from 0 to 15. (Field size : 1 byte)
  3362.  
  3363.  
  3364. Example (ANSI C)
  3365. Creates a typeChanPrefix event. Return a pointer to the event or NIL if there is
  3366. not enough memory space.
  3367.  
  3368. MidiEvPtr ChanPrefix ( long date, short prefix)
  3369. {
  3370.     MidiEvPtr e;
  3371.     long    c=0;
  3372.  
  3373.     if ( e = MidiNewEv(typeChanPrefix))    /* Allocate a new event. 
  3374.                                 Check not NIL    */ 
  3375.     {
  3376.         Date(e) = date;                    
  3377.         MidiSetField( e, 0, prefix);
  3378.     }
  3379.     return e;
  3380. }
  3381.  
  3382. æKY typeCuePoint
  3383. æC 
  3384. typeCuePoint  (code 141)
  3385.  
  3386. Event Description
  3387. A cue point event (from the MidiFile 1.0 specification). This event cannot be sent
  3388. to external Midi devices.
  3389.  
  3390.  
  3391. Fields : typeCuePoint events have a variable number of character fields. 
  3392.  
  3393.  
  3394. Example 1 (ANSI C)
  3395. Creates a typeCuePoint event from a character string. Return a pointer to the event
  3396. or NIL if there is not enough memory space.
  3397.  
  3398. MidiEvPtr CuePoint ( long date, char *s, short chan, short port)
  3399. {
  3400.     MidiEvPtr e;
  3401.     long    c=0;
  3402.  
  3403.     if ( e = MidiNewEv(typeCuePoint))    /* Allocate a new event. 
  3404.                                 Check not NIL    */ 
  3405.     {
  3406.         Date(e) = date;        /* These informations are common to all    */
  3407.         Chan(e) = chan;        /* kind of events        */
  3408.         Port(e) = port;
  3409.         for (c=0; *s; s++, c++)     /* Build the event while counting the    */
  3410.             MidiAddField(e ,*s);/* characters of the original string    */
  3411.         if (c != MidiCountFields(e)) {    /* Check the length of the event        */
  3412.             MidiFreeEv(e);        /* if we run out of memory : free the    */
  3413.             return 0;            /* event and return NIL        */
  3414.         }
  3415.     }
  3416.     return e;
  3417. }
  3418.  
  3419. Example 2 (ANSI C)
  3420. Convert a typeCuePoint event into a character string. Assume s big enough.
  3421.  
  3422. void GetText (MidiEvPtr e, char *s)
  3423. {
  3424.     short c=0, i=0;
  3425.     
  3426.     c = MidiCountFields(e);
  3427.     while (i<c) *s++ = MidiGetField(e, i++);
  3428.     *s = 0;
  3429. }
  3430.  
  3431. æKY typeDProcess
  3432. æC 
  3433. typeDProcess  (code 129)
  3434.  
  3435.  
  3436. Event Description
  3437. DProcess events are automatically created by MidiDTask. They are used to realize
  3438. time delayed procedure call. Once the scheduling date is due, the routine is not
  3439. automatically executed, but stored in a special list. It is the application responsability
  3440. to execute, one by one, those pending tasks using MidiExec1DTask.
  3441.  
  3442.  
  3443. Fields : DProcess events have 4 fields numbered from 0 to 3 :
  3444.  
  3445.     0 - a TaskPtr, the adress of the procedure to call. (Field size : 4 byte)
  3446.     1 - the first argument of the procedure. (Field size : 4 byte)
  3447.     2 - the second argument of the procedure. (Field size : 4 byte)
  3448.     3 - the third argument of the procedure. (Field size : 4 byte)
  3449.  
  3450.  
  3451. Example (ANSI C)
  3452. Creates a DProcess event in the same way than MidiDTask.
  3453.  
  3454. MidiEvPtr MakeDTask ( TaskPtr proc, long date, short refNum, long arg1,
  3455.                     long arg2, long arg3)
  3456. {
  3457.     MidiEvPtr e;
  3458.  
  3459.     if ( e = MidiNewEv( typeDProcess ) )/* Allocate a new event. 
  3460.                                 Check not NIL    */ 
  3461.     {
  3462.         MidiSetField(e, 0, (long)proc);    /* Fill the 4 fields */
  3463.         MidiSetField(e, 1, arg1);
  3464.         MidiSetField(e, 2, arg2);
  3465.         MidiSetField(e, 3, arg3);
  3466.         MidiSendAt(refNum, e, date); /* and schedule the differed task*/
  3467.     }
  3468.     return e;
  3469. }
  3470.  
  3471. æKY typeEndTrack
  3472. æC 
  3473. typeEndTrack  (code 143)
  3474.  
  3475. Event Description
  3476. An end of track event (from the MidiFile 1.0 specification). This event cannot
  3477. be sent to external Midi devices.
  3478.  
  3479.  
  3480. Fields : typeEndTrack  events have no field. 
  3481.  
  3482. Example (ANSI C)
  3483. Creates a typeEndTrack  event. Return a pointer to the event or NIL if there is
  3484. not enough memory space.
  3485.  
  3486. MidiEvPtr EndTrack ( long date )
  3487. {
  3488.     MidiEvPtr e;
  3489.  
  3490.     if ( e = MidiNewEv(typeEndTrack))    /* Allocate a new event.
  3491.                                     Check not NIL    */ 
  3492.     {
  3493.         Date(e) = date;                    
  3494.     }
  3495.     return e;
  3496. }
  3497.  
  3498. æKY typeInstrName
  3499. æC 
  3500. typeInstrName  (code 138)
  3501.  
  3502. Event Description
  3503. An instrument name event (from the MidiFile 1.0 specification). This event cannot
  3504. be sent to external Midi devices.
  3505.  
  3506.  
  3507. Fields : typeInstrName events have a variable number of character fields. 
  3508.  
  3509. Example 1 (ANSI C)
  3510. Creates a typeInstrName event from a character string. Return a pointer to the
  3511. event or NIL if there is not enough memory space.
  3512.  
  3513. MidiEvPtr InstrName ( long date, char *s, short chan, short port)
  3514. {
  3515.     MidiEvPtr e;
  3516.     long    c=0;
  3517.  
  3518.     if ( e = MidiNewEv(typeInstrName) )    /* Allocate a new event. 
  3519.                                     Check not NIL    */ 
  3520.     {
  3521.         Date(e) = date;        /* These informations are common to all    */
  3522.         Chan(e) = chan;        /* kind of events        */
  3523.         Port(e) = port;
  3524.         for (c=0; *s; s++, c++)     /* Build the event while counting the    */
  3525.             MidiAddField(e ,*s);/* characters of the original string    */
  3526.         if (c != MidiCountFields(e)) {    /* Check the length of the event*/
  3527.             MidiFreeEv(e);        /* if we run out of memory : free the    */
  3528.             return 0;            /* event and return NIL        */
  3529.         }
  3530.     }
  3531.     return e;
  3532. }
  3533.  
  3534. Example 2 (ANSI C)
  3535. Convert a typeInstrName event into a character string. Assume s big enough.
  3536.  
  3537. void GetText (MidiEvPtr e, char *s)
  3538. {
  3539.     short c=0, i=0;
  3540.     
  3541.     c = MidiCountFields(e);
  3542.     while (i<c) *s++ = MidiGetField(e, i++);
  3543.     *s = 0;
  3544. }
  3545.  
  3546. æKY typeKeyOff
  3547. æC 
  3548. typeKeyOff  (code 2)
  3549.  
  3550. Event Description
  3551. A Note Off message with pitch and velocity. 
  3552.  
  3553. Fields : KeyOff events have 2 fields numbered from 0 to 1 :
  3554.  
  3555.     0 - Pitch, a note number from 0 to 127. (Field size : 1 byte)
  3556.     1 - Vel, a note velocity from 0 to 127. (Field size : 1 byte)
  3557.  
  3558. Example 1 (ANSI C)
  3559. Creates a KeyOff event. Return a pointer to the event or NIL if there is no more
  3560. memory space. Fields are modified using MidiSetField instead of direct structure
  3561. access.
  3562.  
  3563. MidiEvPtr KeyOff( long date, short pitch, short vel, short chan, short port)
  3564. {
  3565.     MidiEvPtr e;
  3566.  
  3567.     if ( e = MidiNewEv( typeKeyOff ) )     /* Allocate a new event. 
  3568.                                     Check not NIL    */ 
  3569.     {
  3570.         Date(e) = date;        /* These informations are common to all    */
  3571.         Chan(e) = chan;        /* kind of events        */
  3572.         Port(e) = port;
  3573.         MidiSetField(e,0,pitch);    /* These fields are particular 
  3574.                             to KeyOff    */
  3575.         MidiSetField(e,1,vel);
  3576.     }
  3577.     return e;
  3578. }
  3579.  
  3580. Example 2 (ANSI C)
  3581. Creates a KeyOff event. Return a pointer to the event or NIL if there is no more
  3582. memory space. Fields are modified using direct structure access instead of MidiSetField.
  3583.  
  3584. MidiEvPtr KeyKeyOff( long date, short pitch, short vel, short chan, short port)
  3585. {
  3586.     MidiEvPtr e;
  3587.  
  3588.     if ( e = MidiNewEv( typeKeyOff ) )     /* Allocate a new event. 
  3589.                                 Check not NIL    */ 
  3590.     {
  3591.         Date(e) = date;        /* These informations are common to all    */
  3592.         Chan(e) = chan;        /* kind of events        */
  3593.         Port(e) = port;
  3594.         Pitch(e) = pitch;    /* These fields are particular to KeyOff*/
  3595.         Vel(e)     = vel;
  3596.     }
  3597.     return e;
  3598. }
  3599.  
  3600. æKY typeKeyOn
  3601. æC 
  3602. typeKeyOn  (code 1)
  3603.  
  3604. Event Description
  3605. A Note On message with pitch and velocity. 
  3606.  
  3607. Fields : KeyOn events have 2 fields numbered from 0 to 1 :
  3608.  
  3609.     0 - Pitch, a note number from 0 to 127. (Field size : 1 byte)
  3610.     1 - Vel, a note velocity from 0 to 127. (Field size : 1 byte)
  3611.  
  3612. Example 1 (ANSI C)
  3613. Creates a KeyOn event. Return a pointer to the event or NIL if there is no more
  3614. memory space. Fields are modified using MidiSetField instead of direct structure
  3615. access.
  3616.  
  3617. MidiEvPtr KeyOn( long date, short pitch, short vel, short chan, short port)
  3618. {
  3619.     MidiEvPtr e;
  3620.  
  3621.     if ( e = MidiNewEv( typeKeyOn ) )     /* Allocate a new event. 
  3622.                                 Check not NIL    */ 
  3623.     {
  3624.         Date(e) = date;        /* These informations are common to all    */
  3625.         Chan(e) = chan;        /* kind of events        */
  3626.         Port(e) = port;
  3627.         MidiSetField(e,0,pitch);/* These fields are particular to KeyOn*/
  3628.         MidiSetField(e,1,vel);
  3629.     }
  3630.     return e;
  3631. }
  3632.  
  3633. Example 2 (ANSI C)
  3634. Creates a KeyOn event. Return a pointer to the event or NIL if there is no more
  3635. memory space. Fields are modified using direct structure access instead of MidiSetField.
  3636.  
  3637. MidiEvPtr KeyOn( long date, short pitch, short vel, short chan, short port)
  3638. {
  3639.     MidiEvPtr e;
  3640.  
  3641.     if ( e = MidiNewEv( typeKeyOn ) )     /* Allocate a new event. 
  3642.                                 Check not NIL    */ 
  3643.     {
  3644.         Date(e) = date;        /* These informations are common to all    */
  3645.         Chan(e) = chan;        /* kind of events        */
  3646.         Port(e) = port;
  3647.         Pitch(e) = pitch;    /* These fields are particular to KeyOn */
  3648.         Vel(e)     = vel;
  3649.     }
  3650.     return e;
  3651. }
  3652.  
  3653. æKY typeKeyPress
  3654. æC 
  3655. typeKeyPress  (code 3)
  3656.  
  3657. Event Description
  3658. A Polyphonic Key Pressure message with pitch and pressure. 
  3659.  
  3660. Fields : KeyPress events have 2 fields numbered from 0 to 1 :
  3661.  
  3662.     0 - Pitch, a note number from 0 to 127. (Field size : 1 byte)
  3663.     1 - Press, a key pressure from 0 to 127. (Field size : 1 byte)
  3664.  
  3665. Example 1 (ANSI C)
  3666. Creates a KeyPress event. Return a pointer to the event or NIL if there is no more
  3667. memory space. Fields are modified using MidiSetField instead of direct structure
  3668. access.
  3669.  
  3670. MidiEvPtr KeyPress( long date, short pitch, short press, short chan, short port)
  3671. {
  3672.     MidiEvPtr e;
  3673.  
  3674.     if ( e = MidiNewEv( typeKeyPress ) )/* Allocate a new event. 
  3675.                                 Check not NIL    */ 
  3676.     {
  3677.         Date(e) = date;        /* These informations are common to all    */
  3678.         Chan(e) = chan;        /* kind of events        */
  3679.         Port(e) = port;
  3680.         MidiSetField(e,0,pitch);    /* These fields are particular 
  3681.                                 to KeyPress    */
  3682.         MidiSetField(e,1,press);
  3683.     }
  3684.     return e;
  3685. }
  3686.  
  3687. Example 2 (ANSI C)
  3688. Creates a KeyPress event. Return a pointer to the event or NIL if there is no more
  3689. memory space. Fields are modified using direct structure access instead of MidiSetField.
  3690.  
  3691. MidiEvPtr KeyPress( long date, short pitch, short press, short chan, short port)
  3692. {
  3693.     MidiEvPtr e;
  3694.  
  3695.     if ( e = MidiNewEv( typeKeyPress ) )/* Allocate a new event. 
  3696.                                 Check not NIL    */ 
  3697.     {
  3698.         Date(e) = date;        /* These informations are common to all    */
  3699.         Chan(e) = chan;        /* kind of events                    */
  3700.         Port(e) = port;
  3701.         Pitch(e) = pitch;    /* These fields are particular to KeyPress*/
  3702.         Vel(e)     = press;        /* Same byte than velocity            */
  3703.     }
  3704.     return e;
  3705. }
  3706.  
  3707. æKY typeKeySign
  3708. æC 
  3709. typeKeySign  (code 147)
  3710.  
  3711. Event Description
  3712. A Key Signature event (form the MidiFile 1.0 specification). This event cannot
  3713. be sent to external Midi devices. 
  3714.  
  3715. Fields : typeKeySign events have 2 fields :
  3716.  
  3717.     0 - from -7 (7 flats) to 7 (7 sharps), (8-bits field)
  3718.     1 -  form 0 (major key) to 1 (minor key), (8-bits field)
  3719.  
  3720. Example (ANSI C)
  3721. Creates a Key Signature event. Return a pointer to the event or NIL if there is
  3722. no more memory space.
  3723.  
  3724. MidiEvPtr KeySign (long date, long sharpflats, long minor)
  3725. {
  3726.     MidiEvPtr e;
  3727.  
  3728.     if ( e = MidiNewEv(typeKeySign))    /* Allocate a new event. 
  3729.                                     Check not NIL    */ 
  3730.     {
  3731.         Date(e) = date;                    
  3732.         MidiSetField(e, 0, sharpflats);
  3733.         MidiSetField(e, 1, minor);
  3734.     }
  3735.     return e;
  3736. }
  3737.  
  3738. æKY typeLyric
  3739. æC 
  3740. typeLyric  (code 139)
  3741.  
  3742. Event Description
  3743. A lyric event (from the MidiFile 1.0 specification). This event cannot be sent
  3744. to external Midi devices.
  3745.  
  3746. Fields : typeLyric events have a variable number of character fields. 
  3747.  
  3748. Example 1 (ANSI C)
  3749. Creates a typeLyric event from a character string. Return a pointer to the event
  3750. or NIL if there is not enough memory space.
  3751.  
  3752. MidiEvPtr Lyric ( long date, char *s, short chan, short port)
  3753. {
  3754.     MidiEvPtr e;
  3755.     long    c=0;
  3756.  
  3757.     if ( e = MidiNewEv(typeLyric) )        /* Allocate a new event. 
  3758.                                     Check not NIL    */ 
  3759.     {
  3760.         Date(e) = date;        /* These informations are common to all    */
  3761.         Chan(e) = chan;        /* kind of events    */
  3762.         Port(e) = port;
  3763.         for (c=0; *s; s++, c++) /* Build the event while counting the    */
  3764.             MidiAddField(e ,*s);/* characters of the original string    */
  3765.         if (c != MidiCountFields(e)) {    /* Check the length of the event*/
  3766.             MidiFreeEv(e);    /* if we run out of memory : free the    */
  3767.             return 0;        /* event and return NIL        */
  3768.         }
  3769.     }
  3770.     return e;
  3771. }
  3772.  
  3773. Example 2 (ANSI C)
  3774. Convert a typeLyric event into a character string. Assume s big enough.
  3775.  
  3776. void GetText (MidiEvPtr e, char *s)
  3777. {
  3778.     short c=0, i=0;
  3779.     
  3780.     c = MidiCountFields(e);
  3781.     while (i<c) *s++ = MidiGetField(e, i++);
  3782.     *s = 0;
  3783. }
  3784.  
  3785. æKY typeMarker
  3786. æC 
  3787. typeMarker  (code 140)
  3788.  
  3789. Event Description
  3790. A marker event (from the MidiFile 1.0 specification). This event cannot be sent
  3791. to external Midi devices.
  3792.  
  3793. Fields : typeMarker events have a variable number of character fields. 
  3794.  
  3795. Example 1 (ANSI C)
  3796. Creates a typeMarker event from a character string. Return a pointer to the event
  3797. or NIL if there is not enough memory space.
  3798.  
  3799. MidiEvPtr Marker ( long date, char *s, short chan, short port)
  3800. {
  3801.     MidiEvPtr e;
  3802.     long    c=0;
  3803.  
  3804.     if ( e = MidiNewEv(typeMarker))        /* Allocate a new event. 
  3805.                                     Check not NIL*/ 
  3806.     {
  3807.         Date(e) = date;    /* These informations are common to all    */
  3808.         Chan(e) = chan;        /* kind of events                    */
  3809.         Port(e) = port;
  3810.         for (c=0; *s; s++, c++)     /* Build the event while counting the    */
  3811.             MidiAddField(e ,*s);/* characters of the original string    */
  3812.         if (c != MidiCountFields(e)) {    /* Check the length of the event*/
  3813.             MidiFreeEv(e);        /* if we run out of memory : free the    */
  3814.             return 0;            /* event and return NIL        */
  3815.         }
  3816.     }
  3817.     return e;
  3818. }
  3819.  
  3820. Example 2 (ANSI C)
  3821. Convert a typeMarker event into a character string. Assume s big enough.
  3822.  
  3823. void GetText (MidiEvPtr e, char *s)
  3824. {
  3825.     short c=0, i=0;
  3826.     
  3827.     c = MidiCountFields(e);
  3828.     while (i<c) *s++ = MidiGetField(e, i++);
  3829.     *s = 0;
  3830. }
  3831.  
  3832. æKY typeNonRegParam
  3833. æC 
  3834. typeNonRegParam  (code 132)
  3835.  
  3836. Event Description
  3837. A Non Registred Parameter event with a 14-bits parameter number and a 14-bits parameter
  3838. value. When a typeNonRegParam event is sent to external Midi devices, actually
  3839. four control change messages are sent, two to select the non-registerd parameter
  3840. number, and two for the parameter value using the 14-bits data-entry controller.
  3841.  
  3842. Fields : typeNonRegParam events have 2 fields numbered from 0 to 1 :
  3843.  
  3844.     0 - A Non Registred Parameter number from 0 to 16383. (Field size : 2 byte)
  3845.     1 - A parameter value from 0 to 16383. (Field size : 2 byte)
  3846.  
  3847. Example (ANSI C)
  3848. Creates a Non Registred Parameter event. Return a pointer to the event or NIL if
  3849. there is no more memory space.
  3850.  
  3851. MidiEvPtr NonRegParam( long date, short param, short val, short chan, short port)
  3852. {
  3853.     MidiEvPtr e;
  3854.  
  3855.     if (e = MidiNewEv(typeNonRegParam))    /* Allocate a new event. 
  3856.                                     Check not NIL    */ 
  3857.     {
  3858.         Date(e) = date;        /* These informations are common to all    */
  3859.         Chan(e) = chan;        /* kind of events        */
  3860.         Port(e) = port;
  3861.         MidiSetField(e,0,param);    /* Fields particular to NonRegParam     */
  3862.         MidiSetField(e,1,val);
  3863.     }
  3864.     return e;
  3865. }
  3866.  
  3867. æKY typeNote
  3868. æC 
  3869. typeNote  (code 0)
  3870.  
  3871. Event Description
  3872. A note with pitch, velocity and duration. When a Note event is sent to external
  3873. Midi devices, actually a NoteOn message is first sent followed, after a delay specified
  3874. by the duration, by a NoteOn with a velocity of 0 to end the note.
  3875.  
  3876. Fields : Note events have 3 fields numbered from 0 to 2 :
  3877.  
  3878.     0 - Pitch, a note number from 0 to 127. (Field size : 1 byte)
  3879.     1 - Vel, a note velocity from 0 to 127. (Field size : 1 byte)
  3880.     2 - Dur, a note duration from 0 to 215-1. (Field size : 2 bytes)
  3881.  
  3882. Example 1 (ANSI C)
  3883. Creates a Note event. Return a pointer to the event or NIL if there is no more
  3884. memory space. Fields are modified using MidiSetField instead of direct structure
  3885. access.
  3886.  
  3887. MidiEvPtr Note(long date,short pitch,short vel,short duration,short chan,short
  3888. port) {
  3889.     MidiEvPtr e;
  3890.  
  3891.     if ( e = MidiNewEv( typeNote ) )     /* Allocate a new event. 
  3892.                                     Check not NIL    */ 
  3893.     {
  3894.         Date(e) = date;        /* These informations are common to all    */
  3895.         Chan(e) = chan;        /* kind of events        */
  3896.         Port(e) = port;
  3897.         MidiSetField(e,0,pitch); /* These fields are particular to Notes*/
  3898.         MidiSetField(e,1,vel);
  3899.         MidiSetField(e,2,dur);
  3900.     }
  3901.     return e;
  3902. }
  3903.  
  3904. Example 2 (ANSI C)
  3905. Creates a Note event. Return a pointer to the event or NIL if there is no more
  3906. memory space. Fields are modified using direct structure access instead of MidiSetField.
  3907.  
  3908. MidiEvPtr Note(long date,short pitch,short vel,short duration,short chan,short
  3909. port) {
  3910.     MidiEvPtr e;
  3911.  
  3912.     if ( e = MidiNewEv( typeNote ) )     /* Allocate a new event. 
  3913.                                     Check not NIL    */ 
  3914.     {
  3915.         Date(e) = date;        /* These informations are common to all    */
  3916.         Chan(e) = chan;        /* kind of events                    */
  3917.         Port(e) = port;
  3918.         Pitch(e) = pitch;    /* These fields are particular to Notes    */
  3919.         Vel(e)     = vel;
  3920.         Dur(e)     = dur;
  3921.     }
  3922.     return e;
  3923. }
  3924.  
  3925. æKY typePitchWheel
  3926. æC 
  3927. typePitchWheel  (code 7)
  3928.  
  3929. Event Description
  3930. A Pitch Bender message with a 14 bits resolution. 
  3931.  
  3932. Fields : PitchWheel events have 2 fields numbered from 0 to 1 :
  3933.  
  3934.     0 - LS 7-Bits of 14-bits pitch swing, from 0 to 127. (Field size : 1 byte)
  3935.     1 - MS 7-Bits of 14-bits pitch swing, from 0 to 127. (Field size : 1 byte)
  3936.  
  3937. Example (ANSI C)
  3938. Creates a PitchWheel  event with a parameter between -8192 and 8191. Return a pointer
  3939. to the event or NIL if there is no more memory space.
  3940.  
  3941. MidiEvPtr PitchWheel( long date, short wheel, short chan, short port)
  3942. {
  3943.     const offset = 8192;
  3944.     const min = -8192;
  3945.     const max = 8191;
  3946.     MidiEvPtr e;
  3947.  
  3948.     wheel = (wheel>max) ? max : (wheel<min) ? min : wheel;
  3949.  
  3950.     if ( e = MidiNewEv( typePitchWheel ) )    /* Allocate a new event. 
  3951.                                     Check not NIL    */ 
  3952.     {
  3953.         Date(e) = date;        /* These informations are common to all    */
  3954.         Chan(e) = chan;        /* kind of events        */
  3955.         Port(e) = port;
  3956.         MidiSetField(e,0,(wheel+offset) & 0x7F);    /* LS-7bits Field    */
  3957.         MidiSetField(e,1,(wheel+offset)>>7 & 0x7F);    /* MS-7bits Field    */
  3958.     }
  3959.     return e;
  3960. }
  3961.  
  3962. æKY typePrivate
  3963. æC 
  3964. typePrivate  (code 19 to 127)
  3965.  
  3966. Event Description
  3967. A private event with 4 fields which can be freely used by the application.
  3968.  
  3969. Fields : Private events have 4 fields numbered from 0 to 3.
  3970.     Fields size : 4 bytes
  3971.  
  3972. Example (ANSI C)
  3973. <to be supplied>
  3974.  
  3975. æKY typeProcess
  3976. æC 
  3977. typeProcess  (code 128)
  3978.  
  3979. Event Description
  3980. Process events are automatically created by MidiCall and MidiTask. They are used
  3981. to realize time delayed procedure call. The procedure call is achieved under interrupts
  3982. as soon as the scheduling date is due.
  3983.  
  3984. Fields : Process events have 4 fields numbered from 0 to 3 :
  3985.  
  3986.     0 - a TaskPtr, the adress of the procedure to call. (Field size : 4 byte)
  3987.     1 - the first argument of the procedure. (Field size : 4 byte)
  3988.     2 - the second argument of the procedure. (Field size : 4 byte)
  3989.     3 - the third argument of the procedure. (Field size : 4 byte)
  3990.  
  3991. Example (ANSI C)
  3992. Creates a Process event in the same way than MidiTask.
  3993.  
  3994. MidiEvPtr MakeTask ( TaskPtr proc, long date, short refNum, long arg1,
  3995.                     long arg2, long arg3)
  3996. {
  3997.     MidiEvPtr e;
  3998.  
  3999.     if ( e = MidiNewEv( typeProcess ) )    /* Allocate a new event. 
  4000.                                     Check not NIL    */ 
  4001.     {
  4002.         MidiSetField(e, 0, (long)proc);    /* Fill the 4 fields    */
  4003.         MidiSetField(e, 1, arg1);
  4004.         MidiSetField(e, 2, arg2);
  4005.         MidiSetField(e, 3, arg3);
  4006.         MidiSendAt(refNum, e, date);    /* and schedule the task    */
  4007.     }
  4008.     return e;
  4009. }
  4010.  
  4011. æKY typeProgChange
  4012. æC 
  4013. typeProgChange  (code 5)
  4014.  
  4015. Event Description
  4016. A Program Change message with a program number. 
  4017.  
  4018. Fields : ProgChange events have 1 field numbered 0 :
  4019.  
  4020.     0 - A program number from 0 to 127. (Field size : 1 byte)
  4021.  
  4022. Example (ANSI C)
  4023. Creates a ProgChange event. Return a pointer to the event or NIL if there is no
  4024. more memory space.
  4025.  
  4026. MidiEvPtr ProgChange( long date, short prog, short chan, short port)
  4027. {
  4028.     MidiEvPtr e;
  4029.  
  4030.     if ( e = MidiNewEv( typeProgChange ) )/* Allocate a new event. Check not NIL*/
  4031.      {
  4032.         Date(e) = date;        /* These informations are common to all    */
  4033.         Chan(e) = chan;        /* kind of events        */
  4034.         Port(e) = port;
  4035.         MidiSetField(e,0,prog);    /* Field particular to ProgChange    */
  4036.     }
  4037.     return e;
  4038. }
  4039.  
  4040. æKY typeQuarterFrame
  4041. æC 
  4042. typeQuarterFrame  (code 130)
  4043.  
  4044. Event Description
  4045. A Midi time code quarter frame message with message type and value. These two fields
  4046. are automatically assembled by MidiShare into one byte when the message is sent.
  4047.  
  4048.  
  4049. Fields : QuarterFrame events have 2 fields numbered from 0 to 1 :
  4050.  
  4051.     0 - A message type from 0=Frame count LSB nibble to 7=Hours count MS nibble. (Field
  4052. size : 1 byte)     1 - A count nibble from 0 to 15. (Field size : 1 byte)
  4053.  
  4054. Example (ANSI C)
  4055. Creates a QuarterFrame event. Return a pointer to the event or NIL if there is
  4056. no more memory space.
  4057.  
  4058. MidiEvPtr QuarterFrame( long date, short type, short nibble, short port)
  4059. {
  4060.     MidiEvPtr e;
  4061.  
  4062.     if ( e = MidiNewEv( typeQuarterFrame ) )/* Allocate a new event. 
  4063.                                     Check not NIL    */ 
  4064.     {
  4065.         Date(e) = date;        /* These informations are common to all    */
  4066.         Port(e) = port;        /* kind of events                    */
  4067.         MidiSetField(e,0,type);    /* Fields particular to QuarterFrame     */
  4068.         MidiSetField(e,1,nibble);
  4069.     }
  4070.     return e;
  4071. }
  4072.  
  4073. æKY typeRegParam
  4074. æC 
  4075. typeRegParam  (code 133)
  4076.  
  4077. Event Description
  4078. A Registred Parameter event with a 14-bits parameter number and a 14-bits parameter
  4079. value. When a typeRegParam event is sent to external Midi devices, actually four
  4080. control change messages are sent, two to select the registred parameter number,
  4081. and two for the parameter value using the 14-bits data-entry controller.
  4082.  
  4083. Fields : typeRegParam events have 2 fields numbered from 0 to 1 :
  4084.  
  4085.     0 - A Registred Parameter number from 0 to 16383. (Field size : 2 byte)
  4086.     1 - A Registerd Parameter value from 0 to 16383. (Field size : 2 byte)
  4087.  
  4088. Example (ANSI C)
  4089. Creates a Registred Parameter event. Return a pointer to the event or NIL if there
  4090. is no more memory space.
  4091.  
  4092. MidiEvPtr RegParam( long date, short param, short val, short chan, short port)
  4093. {
  4094.     MidiEvPtr e;
  4095.  
  4096.     if ( e = MidiNewEv( typeRegParam ) )/* Allocate a new event. 
  4097.                                     Check not NIL    */ 
  4098.     {
  4099.         Date(e) = date;        /* These informations are common to all    */
  4100.         Chan(e) = chan;        /* kind of events        */
  4101.         Port(e) = port;
  4102.         MidiSetField(e,0,param);    /* Fields particular to RegParam     */
  4103.         MidiSetField(e,1,val);
  4104.     }
  4105.     return e;
  4106. }
  4107.  
  4108. æKY typeReserved
  4109. æC 
  4110. typeReserved  (code 149 to 254)
  4111.  
  4112. Event Description
  4113.  
  4114. These events are reserved for future use.
  4115.  
  4116. æKY typeReset
  4117. æC 
  4118. typeReset  (code 16)
  4119.  
  4120. Event Description
  4121. A Real Time Reset message. 
  4122.  
  4123. Fields : Reset events have no field.
  4124.  
  4125. Example (ANSI C)
  4126. Creates a Reset event. Return a pointer to the event or NIL if there is no more
  4127. memory space.
  4128.  
  4129. MidiEvPtr Reset ( long date, short port)
  4130. {
  4131.     MidiEvPtr e;
  4132.  
  4133.     if ( e = MidiNewEv( typeReset ) )/* Allocate a new event. 
  4134.                                 Check not NIL*/ 
  4135.     {
  4136.         Date(e) = date;        /* These informations are common to all    */
  4137.         Port(e) = port;        /* kind of events        */
  4138.     }
  4139.     return e;
  4140. }
  4141.  
  4142. æKY typeSeqName
  4143. æC 
  4144. typeSeqName  (code 137)
  4145.  
  4146. Event Description
  4147. A sequence name event (from the MidiFile 1.0 specification). This event cannot
  4148. be sent to external Midi devices.
  4149.  
  4150. Fields : typeSeqName events have a variable number of character fields. 
  4151.  
  4152. Example 1 (ANSI C)
  4153. Creates a typeSeqName event from a character string. Return a pointer to the event
  4154. or NIL if there is not enough memory space.
  4155.  
  4156. MidiEvPtr SeqName ( long date, char *s, short chan, short port)
  4157. {
  4158.     MidiEvPtr e;
  4159.     long    c=0;
  4160.  
  4161.     if ( e = MidiNewEv( typeSeqName ) )    /* Allocate a new event. 
  4162.                                     Check not NIL    */ 
  4163.     {
  4164.         Date(e) = date;        /* These informations are common to all    */
  4165.         Chan(e) = chan;        /* kind of events        */
  4166.         Port(e) = port;
  4167.         for (c=0; *s; s++, c++)     /* Build the event while counting the    */
  4168.             MidiAddField(e ,*s);/* characters of the original string    */
  4169.         if (c != MidiCountFields(e)) {    /* Check the length of the event        */
  4170.             MidiFreeEv(e);        /* if we run out of memory : free the    */
  4171.             return 0;        /* event and return NIL            */
  4172.         }
  4173.     }
  4174.     return e;
  4175. }
  4176.  
  4177. Example 2 (ANSI C)
  4178. Convert a typeSeqName event into a character string. Assume s big enough.
  4179.  
  4180. void GetText (MidiEvPtr e, char *s)
  4181. {
  4182.     short c=0, i=0;
  4183.     
  4184.     c = MidiCountFields(e);
  4185.     while (i<c) *s++ = MidiGetField(e, i++);
  4186.     *s = 0;
  4187. }
  4188.  
  4189. æKY typeSeqNum
  4190. æC 
  4191. typeSeqNum  (code 134)
  4192.  
  4193. Event Description
  4194. A Sequence number event (form the MidiFile 1.0 specification). This event cannot
  4195. be sent to external Midi devices. 
  4196.  
  4197. Fields : typeSeqNum events have 1 field :
  4198.  
  4199.     0 - Sequence number form 0 to 65535 (2-bytes field)
  4200.  
  4201. Example (ANSI C)
  4202. Creates a Sequence Number event. Return a pointer to the event or NIL if there
  4203. is no more memory space.
  4204.  
  4205. MidiEvPtr SeqNum( long date, short num, short port)
  4206. {
  4207.     MidiEvPtr e;
  4208.  
  4209.     if ( e = MidiNewEv( typeSeqNum) )    /* Allocate a new event. 
  4210.                                     Check not NIL    */ 
  4211.     {
  4212.         Date(e) = date;        /* These informations are common to all    */
  4213.         Port(e) = port;        /* kind of events        */
  4214.         MidiSetField(e,0,num);    /* the sequence number field    */
  4215.     }
  4216.     return e;
  4217. }
  4218.  
  4219. æKY typeSMPTEOffset
  4220. æC 
  4221. typeSMPTEOffset  (code 145)
  4222.  
  4223. Event Description
  4224. An SMPTE Offset event (form the MidiFile 1.0 specification). This event cannot
  4225. be sent to external Midi devices. 
  4226.  
  4227. Fields : typeSMPTEOffset events have 2 fields :
  4228.  
  4229.     0 - Hours, minutes and seconds parts of the SMPTE Offset in seconds from 0 to
  4230. 1048575 (20-bits field)     1 - Frames and 100ths of a frame part of the SMPTE Offset
  4231. in 100ths of a frame form 0 to 4095 (12-bits field)
  4232.  
  4233. Example 1 (ANSI C)
  4234. Creates an SMPTE Offset event. Return a pointer to the event or NIL if there is
  4235. no more memory space.
  4236.  
  4237. MidiEvPtr SMPTEOffset(long hr, long mn, long sec, long frames, long subframes)
  4238. {
  4239.     MidiEvPtr e;
  4240.  
  4241.     if (e = MidiNewEv(typeSMPTEOffset))    /* Allocate a new event. 
  4242.                                     Check not NIL    */ 
  4243.     {
  4244.         Date(e) = 0;                    
  4245.         MidiSetField(e, 0, hr*3600 + mn*60 + sec);
  4246.         MidiSetField(e, 1, (frames*100 + subframes));
  4247.     }
  4248.     return e;
  4249. }
  4250.  
  4251. Example 2 (ANSI C)
  4252. Read the different parts of an SMPTE Offset event. 
  4253.  
  4254. long GetHours (MidiEvPtr e)
  4255. {
  4256.     return MidiGetField(e,0) / 3600;
  4257. }
  4258.  
  4259. long GetMinutes (MidiEvPtr e)
  4260. {
  4261.     return MidiGetField(e,0) % 3600 / 60;
  4262. }
  4263.  
  4264. long GetSeconds (MidiEvPtr e)
  4265. {
  4266.     return MidiGetField(e,0) % 60;
  4267. }
  4268.  
  4269. long GetFrames (MidiEvPtr e)
  4270. {
  4271.     return MidiGetField(e,1) / 100;
  4272. }
  4273.  
  4274. long GetSubFrames (MidiEvPtr e)
  4275. {
  4276.     return MidiGetField(e,1) % 100;
  4277. }
  4278.  
  4279. æKY typeSongPos
  4280. æC 
  4281. typeSongPos  (code 8)
  4282.  
  4283. Event Description
  4284. A Song Position Pointer message with a 14 bits location (unit : 6 Midi Clocks).
  4285.  
  4286.  
  4287. Fields : SongPos events have 2 fields numbered from 0 to 1 :
  4288.  
  4289.     0 - LS 7-Bits of 14-bits location, from 0 to 127. (Field size : 1 byte)
  4290.     1 - MS 7-Bits of 14-bits location, from 0 to 127. (Field size : 1 byte)
  4291.  
  4292. Example (ANSI C)
  4293. Creates a SongPos  event with a location in Midi clocks. The location is internaly
  4294. divided by 6. Return a pointer to the event or NIL if there is no more memory space.
  4295.  
  4296. MidiEvPtr SongPos( long date, short pos, short port)
  4297. {
  4298.     MidiEvPtr e;
  4299.  
  4300.     pos = pos / 6;
  4301.  
  4302.     if ( e = MidiNewEv( typeSongPos) )    /* Allocate a new event. 
  4303.                                     Check not NIL    */ 
  4304.     {
  4305.         Date(e) = date;        /* These informations are common to all    */
  4306.         Port(e) = port;        /* kind of events        */
  4307.         MidiSetField(e,0,pos & 0x7F);    /* LS-7bits Field            */
  4308.         MidiSetField(e,1,pos>>7 & 0x7F);    /* MS-7bits Field    */
  4309.     }
  4310.     return e;
  4311. }
  4312.  
  4313. æKY typeSongSel
  4314. æC 
  4315. typeSongSel  (code 9)
  4316.  
  4317. Event Description
  4318. A Song Select message with a song number. 
  4319.  
  4320. Fields : SongSel events have 1 field numbered 0 :
  4321.  
  4322.     0 - A song number from 0 to 127. (Field size : 1 byte)
  4323.  
  4324. Example (ANSI C)
  4325. Creates a SongSel event. Return a pointer to the event or NIL if there is no more
  4326. memory space.
  4327.  
  4328. MidiEvPtr SongSel ( long date, short song, short port)
  4329. {
  4330.     MidiEvPtr e;
  4331.  
  4332.     if ( e = MidiNewEv( typeSongSel ) )/* Allocate a new event. 
  4333.                                     Check not NIL    */ 
  4334.     {
  4335.         Date(e) = date;        /* These informations are common to all    */
  4336.         Port(e) = port;        /* kind of events        */
  4337.         MidiSetField(e,0,song);    /* Field particular to SongSel    */
  4338.     }
  4339.     return e;
  4340. }
  4341.  
  4342. æKY typeSpecific
  4343. æC 
  4344. typeSpecific  (code 148)
  4345.  
  4346. Event Description
  4347. A sequencer specific event (from the MidiFile 1.0 specification). This event cannot
  4348. be sent to external Midi devices.
  4349.  
  4350. Fields : typeSpecific events have a variable number of 8-bits fields. 
  4351.  
  4352. Example (ANSI C)
  4353. Creates a typeSpecific event from an array of bytes. Return a pointer to the event
  4354. or NIL if there is no more memory space.
  4355.  
  4356. MidiEvPtr Specific ( long date, short len, Byte *p)
  4357. {
  4358.     MidiEvPtr e;
  4359.     short    c;
  4360.  
  4361.     if ( e = MidiNewEv( typeStream ) )    /* Allocate a new event. 
  4362.                                     Check not NIL    */ 
  4363.     {
  4364.         Date(e) = date;
  4365.         c = len;                    
  4366.         while (c--) MidiAddField(e,*p++);
  4367.         if (MidiCountFields(e) < len ) /* if event smaller than len then*/
  4368.         {
  4369.             MidiFreeEv(e);        /*     we run out of memory, free it    */
  4370.             e = nil;            /*     and return nil        */
  4371.         }
  4372.     }
  4373.     return e;
  4374. }
  4375.  
  4376. æKY typeStart
  4377. æC 
  4378. typeStart  (code 11)
  4379.  
  4380. Event Description
  4381. A Real Time Start message. 
  4382.  
  4383. Fields : Start events have no field.
  4384.  
  4385. Example (ANSI C)
  4386. Creates a Start event. Return a pointer to the event or NIL if there is no more
  4387. memory space.
  4388.  
  4389. MidiEvPtr Start ( long date, short port)
  4390. {
  4391.     MidiEvPtr e;
  4392.  
  4393.     if ( e = MidiNewEv( typeStart ) )/* Allocate a new event. 
  4394.                                 Check not NIL*/ 
  4395.     {
  4396.         Date(e) = date;        /* These informations are common to all    */
  4397.         Port(e) = port;        /* kind of events        */
  4398.     }
  4399.     return e;
  4400. }
  4401.  
  4402. æKY typeStop
  4403. æC 
  4404. typeStop  (code 13)
  4405.  
  4406. Event Description
  4407. A Real Time Stop message. 
  4408.  
  4409. Fields : Stop events have no field.
  4410.  
  4411. Example (ANSI C)
  4412. Creates a Stop event. Return a pointer to the event or NIL if there is no more
  4413. memory space.
  4414.  
  4415. MidiEvPtr Stop ( long date, short port)
  4416. {
  4417.     MidiEvPtr e;
  4418.  
  4419.     if ( e = MidiNewEv( typeStop ) )/* Allocate a new event. 
  4420.                                 Check not NIL    */ 
  4421.     {
  4422.         Date(e) = date;        /* These informations are common to all    */
  4423.         Port(e) = port;        /* kind of events        */
  4424.     }
  4425.     return e;
  4426. }
  4427.  
  4428. æKY typeStream
  4429. æC 
  4430. typeStream  (code 18)
  4431.  
  4432. Event Description
  4433. Stream message are arbitrary stream of bytes sent by the MidiShare driver without
  4434. any processing. 
  4435.  
  4436. Fields : Stream events have a variable number of fields. 
  4437.  
  4438. Example (ANSI C)
  4439. Creates a Stream event from an array of short. Return a pointer to the event or
  4440. NIL if there is no more memory space.
  4441.  
  4442. MidiEvPtr Stream ( long date, short len, short *p, short port)
  4443. {
  4444.     MidiEvPtr e;
  4445.     short c;
  4446.  
  4447.     if ( e = MidiNewEv( typeStream ) )    /* Allocate a new event. 
  4448.                                     Check not NIL    */ 
  4449.     {
  4450.         Date(e) = date;        /* These informations are common to all    */
  4451.         Port(e) = port;        /* kind of events        */
  4452.         c = len+1;
  4453.         while (--c) MidiAddField(e,*p++);
  4454.         if (MidiCountFields(e) < len ) /* if event smaller than len then*/
  4455.         {
  4456.             MidiFreeEv(e);        /* we run out of memory, free it*/
  4457.             e = nil;            /* and return nil    */
  4458.         }
  4459.     }
  4460.     return e;
  4461. }
  4462.  
  4463. æKY typeSysEx
  4464. æC 
  4465. typeSysEx  (code 17)
  4466.  
  4467. Event Description
  4468. A System Exclusive message. 
  4469.  
  4470. Fields : SysEx events have a variable number of fields. The leading F0 and tailing
  4471. F7 codes must not be included. They are automatically supplied by MidiShare. The
  4472. channel field of the event is ORed with the first data byte after the manufacturer
  4473. ID. This works for setting the channel of many system exclusive messages.
  4474.  
  4475. Example (ANSI C)
  4476. Creates a SysEx event from an array of short. Return a pointer to the event or
  4477. NIL if there is no more memory space.
  4478.  
  4479. MidiEvPtr SysEx ( long date, short len, short *p, short chan, short port)
  4480. {
  4481.     MidiEvPtr e;
  4482.     short c;
  4483.  
  4484.     if ( e = MidiNewEv( typeSysEx ) )    /* Allocate a new event. 
  4485.                                     Check not NIL    */ 
  4486.     {
  4487.         Date(e) = date;        /* These informations are common to all    */
  4488.         Chan(e) = chan;        /* kind of events        */
  4489.         Port(e) = port;
  4490.         c = len+1;
  4491.         while (--c) MidiAddField(e,*p++);
  4492.         if (MidiCountFields(e) < len ) /* if event smaller than len then*/
  4493.         {
  4494.             MidiFreeEv(e);        /* we run out of memory, free it    */
  4495.             e = nil;            /*     and return nil        */
  4496.         }
  4497.     }
  4498.     return e;
  4499. }
  4500.  
  4501. æKY typeTempo
  4502. æC 
  4503. typeTempo  (code 144)
  4504.  
  4505. Event Description
  4506. A tempo event (from the MidiFile 1.0 specification). This event cannot be sent
  4507. to external Midi devices.
  4508.  
  4509. Fields : typeTempo  events have one field.
  4510.  
  4511.      0 - A tempo value in microseconds/Midi quarter-note 0 to 127. (Field size : 4
  4512. bytes)
  4513.  
  4514. Example 1 (ANSI C)
  4515. Creates a typeTempo event from a floating point tempo value in quarter-notes per
  4516. minutes. Return a pointer to the event or NIL if there is not enough memory space.
  4517.  
  4518. MidiEvPtr TempoChange ( long date, float tempo)
  4519. {
  4520.     MidiEvPtr e;
  4521.  
  4522.     if ( e = MidiNewEv(typeTempo))    /* Allocate a new event. 
  4523.                                 Check not NIL*    / 
  4524.     {
  4525.         Date(e) = date;                    
  4526.         MidiSetField(e, 0, (long)(60000000.0 / tempo));    
  4527.     }
  4528.     return e;
  4529. }
  4530.  
  4531. Example 2 (ANSI C)
  4532. Convert a tempo event in microseconds per quarter-note in a floating point tempo
  4533. value in quarter-notes per minutes.
  4534.  
  4535. float GetTempo (MidiEvPtr e)
  4536. {
  4537.     return 60000000.0 / (float) MidiGetField(e,0);
  4538. }
  4539.  
  4540. æKY typeText
  4541. æC 
  4542. typeText  (code 135)
  4543.  
  4544. Event Description
  4545. A text event (from the MidiFile 1.0 specification). This event cannot be sent to
  4546. external Midi devices.
  4547.  
  4548. Fields : typeText events have a variable number of character fields. 
  4549.  
  4550. Example 1 (ANSI C)
  4551. Creates a typeText event from a character string. Return a pointer to the event
  4552. or NIL if there is not enough memory space.
  4553.  
  4554. MidiEvPtr Text ( long date, char *s, short chan, short port)
  4555. {
  4556.     MidiEvPtr e;
  4557.     long    c=0;
  4558.  
  4559.     if ( e = MidiNewEv( typeText ) )    /* Allocate a new event. 
  4560.                                     Check not NIL    */ 
  4561.     {
  4562.         Date(e) = date;        /* These informations are common to all    */
  4563.         Chan(e) = chan;        /* kind of events        */
  4564.         Port(e) = port;
  4565.         for (c=0; *s; s++, c++)     /* Build the text event while counting    */
  4566.             MidiAddField(e ,*s);    /* the characters 
  4567.                                 of the original string    */
  4568.         if (c != MidiCountFields(e)) {    /* Check the length 
  4569.                                 of the text event    */
  4570.             MidiFreeEv(e);        /* if we run out of memory : free the    */
  4571.             return 0;            /* text event and return NIL    */
  4572.         }
  4573.     }
  4574.     return e;
  4575. }
  4576.  
  4577. Example 2 (ANSI C)
  4578. Convert a typeText event into a character string. Assume s big enough.
  4579.  
  4580. void GetText (MidiEvPtr e, char *s)
  4581. {
  4582.     short c=0, i=0;
  4583.     
  4584.     c = MidiCountFields(e);
  4585.     while (i<c) *s++ = MidiGetField(e, i++);
  4586.     *s = 0;
  4587. }
  4588.  
  4589. æKY typeTimeSign
  4590. æC 
  4591. typeTimeSign  (code 146)
  4592.  
  4593. Event Description
  4594. A Time Signature event (form the MidiFile 1.0 specification). This event cannot
  4595. be sent to external Midi devices. 
  4596.  
  4597. Fields : typeTimeSign events have 4 fields :
  4598.  
  4599.     0 - Numerator (8-bits field)
  4600.     1 - denominator in power of two (8-bits field)
  4601.     2 - Midi Clocks per metronome clicks (8-bits field)
  4602.     3 - notated 32th of note per quarter-note (8-bits field)
  4603.  
  4604. Example (ANSI C)
  4605. Creates a Time Signature event. Return a pointer to the event or NIL if there is
  4606. no more memory space.
  4607.  
  4608. MidiEvPtr TimeSign (long date, long num, long denom, long click, long quarterDef)
  4609. {
  4610.     MidiEvPtr e;
  4611.  
  4612.     if ( e = MidiNewEv(typeTimeSign))    /* Allocate a new event. 
  4613.                                     Check not NIL    */ 
  4614.     {
  4615.         Date(e) = date;                    
  4616.         MidiSetField(e, 0, num);
  4617.         MidiSetField(e, 1, denom);
  4618.         MidiSetField(e, 2, click);
  4619.         MidiSetField(e, 3, quarterDef);
  4620.     }
  4621.     return e;
  4622. }
  4623.  
  4624. æKY typeTune
  4625. æC 
  4626. typeTune  (code 14)
  4627.  
  4628. Event Description
  4629. A Tune message. 
  4630.  
  4631. Fields : Tune events have no field.
  4632.  
  4633. Example (ANSI C)
  4634. Creates a Tune event. Return a pointer to the event or NIL if there is no more
  4635. memory space.
  4636.  
  4637. MidiEvPtr Tune ( long date, short port)
  4638. {
  4639.     MidiEvPtr e;
  4640.  
  4641.     if ( e = MidiNewEv( typeTune ) )/* Allocate a new event. Check not NIL*/ 
  4642.     {
  4643.         Date(e) = date;        /* These informations are common to all    */
  4644.         Port(e) = port;        /* kind of events        */
  4645.     }
  4646.     return e;
  4647. }
  4648.